Linux系统编程(1)

news2024/11/26 5:23:53

父子进程通过两个管道进行通信。

 

伪代码
#include <unistd.h>
void client(int, int), server(int, int);

int main(int argc, char** argv) {
    int pipe1[2], pipe2[2];
    pid_t childpid;

    Pipe(pipe1);
    Pipe(pipe2);

    if ((childpid == Fork()) == 0) {
        // child
        Close(pipe1[1]);
        Close(pipe2[0]);

        server(pipe1[0], pipe2[1]);
        exit(0);
    }

    // parent
    Close(pipe1[0]);
    Close(pipe2[1]);
    client(pipe2[0], pipe1[1]);

    Waitpid(childpid, NULL, 0);
    exit(0);
}

open()函数

int fd;
fd = open("test.txt", O_RDONLY);
if (fd == -1) {
    //错误
}

==========================================
int fd;
//如果文件存在,则截断文件,文件不存在,则创建,并且后面指定了文件的权限
fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP | S_IROTH);

creat()函数

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int fd;
fd = creat(file, 0644);
if (fd == -1) 

和
fd = open(file, O_RWONLY | O_CREAT | O_TRUNC, 0644);
是一样的效果。

read()函数

#include <unistd.h>
ssize_t read(int fd, void* buf, size_t len);

从文件描述符fd对应当前的位置读取len字节到buf中,执行成功返回读取的字节数,失败返回-1并设置errno,

ssize_t ret;
while(len != 0 && (ret = read(fd, buf, len)) != 0) {
    if (ret == -1) {
        if (errno == EINTR) continue;
        perror("read");
        break;
    }
    len -= ret;
    buf += ret;
}

 lseek()查找文件位置

#include <sys/types.h>
#include <unistd.h>

off_t lseek (int fd, off_t pos, int origin);

origin参数主要有一下值:

SEEK_CUR:fd的当前文件位置被设置为当前值+pos(其值可是负数,0,正数),pos为零时,返回当前位置。

SEEK_END:fd的当前位置被设定为文件的当前长度+pos(其值可是负数,0,正数),pos为零时,当前位置为文件的末端。

SEEK_SET:fd的当前位置被设置为pos,pos为零时,偏移值为文件的开头。

此调用执行成功时,返回新的文件位置,执行错误时,返回-1,并且将errno设置为适当值。

//将文件fd的位置设置为1825
ret = lseek(fd, (off_t)1825, SEEK_SET);
if (ret == (off_t)-1)

//将文件的位置设置为文件的末端
ret = lseek(fd, 0, SEEK_END);

//找到文件当前的位置
ret = lseek(fd, 0, SEEK_CUR);

pread()和pwrite()函数

#define _XOPEN_SOURCE 500
#include <unistd.h>
ssize_t pread(int fd, void* buf, size_t count, off_t pos);

此调用会从文件fd的pos位置读取count字节放入到buf中

ssize_t pwrite(int fd, const void*buf, size_t count, off_t pos);

将count字节从buf中写入到fd的文件pos位置

以上两个调用不会改变文件的位置

截短文件ftruncate(int fd, off_t len)和truncate(const char* path, off_t len);

#include <unistd.h>
#include <sys/types.h>
int ftruncate(int fd, off_t len);

int truncate(const char* path, off_t len);

 这两个系统调用会将指定的文件截短成len所指定的长度,不改变文件当前位置。

 select()  

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#define TIMEOUT 5    //select的等待时间,秒为单位
#define BUF_LEN 1024  //读取缓冲区,字节为单位
//编译:    gcc -o select_test select_test.cpp
int main(void) {
    struct timeval tv;
    fd_set readfds;
    int ret;

    // 等候stdin的输入数据
    FD_ZERO(&readfds);
    FD_SET(STDIN_FILENO, &readfds);

    // 等候5秒的时间
    tv.tv_sec = TIMEOUT;
    tv.tv_usec = 0;

    ret = select(STDIN_FILENO+1, &readfds, NULL, NULL, &tv);
    if (ret == -1) {
        perror("select");
        return 1;
    } else if(!ret) {
        printf("%d seconds elapsed.\n", TIMEOUT);
        return 0;
    }
    // 是否可读
    if (FD_ISSET(STDIN_FILENO, &readfds)) {
        char buf[BUF_LEN+1];
        int len;
        // 保证不会遭到阻挡
        len = read(STDIN_FILENO, buf, BUF_LEN);
        if (len == -1) {
            perror("read");
            return 1;
        }
        if (len) {
            buf[len] = '\0';
            printf("read: %s\n", buf);
        }
        return 0;
    }
    fprintf(stderr, "This should not happen!\n");
    return 1;
}

poll()函数

#include <stdio.h>
#include <sys/poll.h>
#include <unistd.h>

#define TIMEOUT 5   //poll的等待时间
/*
使用poll()同时检查由读取stdin以及写入stdout是否会受到阻挡
*/

int main() {
    struct pollfd fds[2];
    int ret;

    // 查看stdin输入
    fds[0].fd = STDIN_FILENO;
    fds[0].events = POLLIN;

    // 查看stdout是否可供写入
    fds[1].fd = STDOUT_FILENO;
    fds[1].events = POLLOUT;

    ret = poll(fds, 2, TIMEOUT*1000);
    if (ret == -1) {
        perror("poll");
        return 1;
    } 
    if (!ret) {
        printf("%d seconds elapsed.\n", TIMEOUT);
        return 0;
    }
    if (fds[0].revents & POLLIN) {
        printf("stdin is readable\n");
    }
    if (fds[1].revents & POLLOUT) {
        printf("stdout is writable\n");
    }
    return 0;
}

运行上述程序

./poll

输出stdout is writable

添加一个输入,运行

./poll < xxxx.txt

stdin is readable

stdout is writable

fdopen()将一个已打开的文件描述符fd转成流

#include <stdio.h>
FILE * fdopen(int fd, const char* mode);

关闭流

fclose()关闭流

#include <stdio.h>
int fclose(FILE* stream);

关闭所有流

#define _GNU_SOURCE
#include <stdio.h>
int fcloseall(void);

一次读取一个字符

#include <stdio.h>
//返回类型需是int类型
int fgetc(FILE* stream);

将字符放回

#include <stdio.h>
int ungetc(int c, FILE* stream);

读取一整行

#include <stdio.h>
char* fgets(char* str, int size, FILE* stream);
char* s;
int c;
s = str;
while(--n>0 && (c = fgetc(stream)) != EOF) {
    *s++ = c;
}
*s = '\0';

遇到d时停止读取

char* s;
int c = 0;
s = str;
while(--n>0 && (c = fgetc(stream)) != EOF && (*s++ = c) != d);
if (c == d)
    *--s = '\0';
else
    *s = '\0';

读取二进制数据

#include <stdio.h>
size_t fread(void* buf, size_t size, size_t nr, FILE* stream);

写入一个字符

#include <stdio.h>
int fputc(int c, FILE* stream);

写入一个字符串

#include <stdio.h>
int fputs(const char* str, FILE* stream)

fputs()会把str所指向的以null分割的字符串全部写入到stream流中,执行成功返回一个非负值,执行失败,返回EOF。

写入二进制数据

#include <stdio.h>
size_t fwrite(void* buf, size_t size, size_t nr, FILE* stream);
执行成功返回写入的元素数目,而不是字节数,执行失败,返回一个小于nr的值,指发生了错误。

 

#include <stdio.h>

int main() {
    FILE* in, *out;
    struct pirate {
        char             name[100];   //姓名
        unsigned long    booty;       
        unsigned int     beard_len;
    } p, blackbeard = {"Edward Teach", 950, 48};

    // 将blackbear写入一个流中,再读出来
    out = fopen("data", "w");
    if (!out) {
        perror("fopen");
        return 1;
    }
    if (!fwrite(&blackbeard, sizeof(struct pirate), 1, out)) {
        perror("fwrite");
        return 1;
    }
    if (fclose(out)) {
        perror("fclose");
        return 1;
    }
    in = fopen("data", "r");
    if (!in) {
        perror("fopen");
        return 1;
    }
    if (!fread(&p, sizeof(struct pirate), 1, in)) {
        perror("fread");
        return 1;
    }
    if (fclose(in)) {
        perror("fclose");
        return 1;
    }
    printf("name=\"%s\" booty=%lu beard_len = %u\n", p.name, p.booty, p.beard_len);
    return 0;
}

查找流fseek()

#include <stdio.h>
int fseek(FILE* stream, long offset, int whence);

 如果whence的值被设置为SEEK_SET,则文件位置会被设置为offset,如果whence的值被设置为SEEK_CUR,则文件位置会被设置为当前位置加上offset,如果whence的值被设置为SEEK_END,则文件的位置会被设置为文件末端加上offset。

执行成功时返回0,清除EOF的指示器并取消ungetc()所造成的影响(如果有的话),发生错误返回-1,并将errno设置为适当值,

 fsetpos()

#include <stdio.h>
int fsetpos(FILE* stream, fpos_t *pos);

将流重新设置为开头

#include <stdio.h>
void rewind(FILE* stream);

//调用如下
rewind(stream)
和下面的功能相同
fseek(stream,0, SEEK_SET);

注意:rewind没有返回值,因此无法传达错误信息,如果要确认错误信息,需要调用之前先清除errno的值,在事后检查。

errno = 0;
rewind(stream);
if (errno)
    //错误

获取当前位置

lseek()函数调用结束会返回当前位置,fseek()函数不会,要获得当前位置使用ftell()函数

#include <stdio.h>
long ftell(TILE* stream);

发生错误返回-1,并且将errno设置为合适的值。

fgetpos()

#include <stdio.h>
int fgetpos(FILE* stream, fpos_t *pos);

成功返回0,并且将位置保存在pos中。

 刷新一个流

#include <stdio.h>
int fflush(FILE* stream);

将流中的数据刷新至内核,如果stream为NULL,则进程中所有的流都会被刷新。

 检查错误ferror()

#include <stdio.h>
int ferror(FILE* stream);

 用于检查流上是否有错误。

feof()用于检测stream上是否设置了EOF指示器。

#include <stdio.h>
int feof(FILE* stream);

 clearerr()用于清除stream之上的错误和EOF指示器。

#include <stdio.h.
void clearerr(FILE* stream);

获得相应的文件描述符

#include <stdio.h>
int fileno(FILE* stream);

设置缓冲模式
 

#include <stdio.h>
int setvbuf(FILE* stream, char* buf, int mod, size_t size);

setvbuf()函数会将stream的缓冲区设置为mode类型,_IONBF:未经缓冲,_IOLBF:行缓冲,_IOFBF:经块缓冲。_IONBF(在此情况下会忽略buf和size)除外,buf会指向一个大小为size字节的缓冲区,而标准IO将以此为特定流的缓冲区,如果buf的值为NULL,则glibc会自动分配一个缓冲区。

打开流之后,必须setvbuf函数,而且必须在对流执行任何操作之前进行.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1049369.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode 盛最多水的容器 双指针

原题链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 题面&#xff1a; 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与…

uni-app:canvas-绘制图形2

效果 代码 <template><view><!-- 创建了一个宽度为300像素&#xff0c;高度为200像素的canvas元素。canvas-id属性被设置为"firstCanvas"&#xff0c;可以用来在JavaScript中获取该canvas元素的上下文对象。 --><canvas style"width:200px…

NPDP和PMP证书有啥区别?建议考哪个?

最近分享了很多项目经理和产品经理的问题&#xff0c;有宝子疑问关于这两个职位最热门的证书——PMP和NPDP究竟有什么区别&#xff1f;如何判断自己应该选择哪个&#xff1f;今天胖圆从证书性质&#xff0c;适合人群以及相关考试信息来给大家解读一下&#xff0c;两者有什么不同…

魔兽世界安装插件后进游戏闪退的一个原因。

最近体验了几个私服的WOW&#xff0c;在找插件的时候&#xff0c;总是会遇到wow群里老哥问一个经典的插件问题&#xff0c;进游戏后提示The user interface is using more than 48MB of memory.Set Script Memory to 0 in the character selection screen;然后有个倒计时&#…

(windows10)设置环境变量简化EVOSUITE的运行

对于可执行的jar evosuite-1.1.0.jar&#xff0c;可以在命令行使用jave -jar执行它 然而&#xff0c;每次进入到jar包所在的目录&#xff0c;有点繁琐&#xff0c;这个命令看上去也有点点长。 那么我们可以设置环境变量EVOSUITE来取代这个命令&#xff0c;也即 set EVOSUITEja…

飞致云开源社区月度动态报告(2023年9月)

自2023年6月起&#xff0c;中国领先的开源软件公司FIT2CLOUD飞致云以月度为单位发布《飞致云开源社区月度动态报告》&#xff0c;旨在向广大社区用户同步飞致云旗下系列开源软件的发展情况&#xff0c;以及当月主要的产品新版本发布、社区运营成果等相关信息。 飞致云开源大屏…

顺序读写函数的介绍:fread fwrite

目录 函数介绍&#xff1a; fwrite&#xff1a; 参数说明&#xff1a; 函数大意&#xff1a; 举例&#xff1a; 文件效果&#xff1a; fread&#xff1a; 函数大意&#xff1a; 举例&#xff1a; 结果展示&#xff1a; 函数介绍&#xff1a; fwrite&#xff1a; 参数说明…

基于SSM+Vue的开放式教学评价管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

美美游玩规划

2023年的国庆 游玩规划&#xff1a; 时间安排是9月29日到10月2日上午&#xff1b; 可以有三个整天加一个上午&#xff0c;上午可以去一个近一点的地方&#xff1b; 可能要去的景点&#xff1a; 天安门广场、颐和园、西单购物中心、故宫、天坛公园、 毛主席纪念堂&#xff08;2…

Python大数据之Python进阶(一)介绍

课程介绍 数据埋点本质上就是进行数据采集&#xff0c;数据埋点是对自身业务数据进行采集。要进行数据埋点就要了解我们的业务程序的开发流程&#xff0c;知道整个数据的传递过程&#xff0c;这样能让我们更加明确数据分析的业务需求&#xff0c;有利于数据埋点的准确性。 在…

小程序如何设置余额充值

在小程序中设置余额充值是一种非常有效的方式&#xff0c;可以帮助商家吸引更多的会员并提高用户的消费频率。下面将介绍如何在小程序中设置余额充值并使用。 第一步&#xff1a;创建充值方案 在小程序管理员后台->营销管理->余额充值页面&#xff0c;添加充值方案。可…

“就地拼柜”与“海外仓”:跨境电商的黄金组合

跨境电商行业一直在迅速发展&#xff0c;消费者可以轻松地在世界各地购买商品&#xff0c;而企业也可以触及全球市场。然而&#xff0c;随着全球市场的扩大&#xff0c;供应链和物流管理变得更加复杂。 在这个背景下&#xff0c;"就地拼柜"和"海外仓"等新…

leetcode(翻转二叉树)

个人主页:Lei宝啊 愿所有美好如期而遇 目录 题目&#xff1a; 思路&#xff1a; 代码&#xff1a; 图解&#xff1a; 题目&#xff1a; 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 思路&#xff1a; 二叉树翻转&#xff0c;无…

bigemap如何添加在线地图图源列表,持续更新中

mapbox: https://www.mapbox.com/contribute/ 包含&#xff1a;卫星影像、电子地图 Arcgis &#xff1a; https://livingatlas.arcgis.com/wayback 包含&#xff1a;卫星影像、历史影像 Arcgis Online&#xff1a;http://services.arcgisonline.com 包含&#x…

免费在线Logo生成器推荐,3款助你轻松获取Logo!

Logo 设计对企业品牌形象至关重要&#xff0c;一个高质量的 Logo 可以为企业带来无形的增值。作为设计师&#xff0c;使用优秀的在线 Logo 设计工具&#xff0c;能极大提高工作效率。本文为大家推荐了 6 款实用的 Logo 免费在线生成器&#xff0c;第一款尤为出色&#xff0c;深…

利用maskrcnn来实现目标检测与追踪

首先下载源代码仓库&#xff0c;链接地址如下&#xff1a; maskrcnn 能够实现的效果如图所示&#xff1a; 该存储库包括&#xff1a; 基于FPN和ResNet101构建的Mask R-CNN的源代码。MS COCO 的训练代码MS COCO 的预训练砝码Jupyter 笔记本&#xff0c;用于可视化每一步的检测…

基于Spring Boot的宠物咖啡馆平台的设计与实现

目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 看护师信息管理 宠物寄养管理 健康状况管理 点单 宠物体验 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已…

基于spring boot的医疗管理系统 /基于java的医疗系统

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&a…

智慧教育:数字化时代的未来教育模式

项目背景 随着技术的进步和互联网的普及&#xff0c;教育机构和学校开始寻求利用先进的技术和创新的教育方法来提高学习效果和管理效率&#xff0c;包括在线教育、远程学习、教育数据分析等方面的发展。智慧教育旨在将这些技术和方法应用于教育领域&#xff0c;以满足学生、教…

IDEA配置本地Maven仓库

IDEA配置本地Maven仓库 1、Maven下载安装2、环境变量配置与验证3、配置本地仓库4、IDEA全局配置本地Maven仓库5、清理下载失败的jar依赖 1、Maven下载安装 Maven官网&#xff1a;https://maven.apache.org/download.cgi 按需下载即可 安装&#xff1a; 直接解压即可 2、环境变…