• Linux 无名管道实现文件复制


    无名管道

            通过一个管道(假象)进行传输数据,但是这个管道的传输方式是单工(半双工)的,就是这个管道允许进行发送和接受数据,不过不能同时进行。

    创建无名管道

            这里用到一个pipe()函数,参数fd[2]为一个数组,用来保存函数返回的两个文件描述符,将fd[0]视为管道的读端,而fd[1]视为管道的写端。这也意味着,需要通过这两个设定的文件描述符进行读写。

    无名管道操作特性

            (1)无名管道只能用于具有亲属关系的进程之间通信(如父子进程)

                            所以要用无名管道,首先需要生成有个父子进程

            (2)对管道的读写可以使用I/O中read()函数、write()函数直接操作文件描述符即可

                             如:write(fd[1],buf,nbyte);

                                    read(fd[0],buf,N);

            (3)无名管道本质是内和空间的内存段,不能使用lseek()函数定位。

            (4)一次性操作,一旦管道中存在的数据被读取,管道将会清除被读取的数据。

            (5)大小固定,写满会阻塞。

    fork函数

    fork创建父子进程 ,父进程得到一个返回值,这个返回值为子进程的ID(一定大于零的整数),子进程同样得到一个返回值但为零。

    父进程读取源文件写入管道

    以及子进程读取管道,写入目标文件

    1. if(pid>0){ //父进程
    2. while((nbyte = read(fdr,buf,N))>0) //父进程读取文件写入管道
    3. write(fd[1],buf,nbyte);
    4. printf("读取成功\n");
    5. }
    6. if(pid==0) //子进程
    7. {
    8. while((nbyte = read(fd[0],buf,N))>0) //子进程从管道中读取,写入文件
    9. write(fdw,buf,nbyte);
    10. }

    源码: 

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include<error.h>
    7. #define N 128
    8. #define errlog(errmsg) do{perror(errmsg);\
    9. printf("--%s--%s--%d--\n",\
    10. __FILE__,__FUNCTION__,__LINE__);\
    11. return -1;}while(0)
    12. int main(int argc,char *argv[])
    13. {
    14. pid_t pid;
    15. int fdr,fdw;
    16. ssize_t nbyte;
    17. int fd[2];
    18. char buf[N] = " ";
    19. if((fdr = open(argv[1],O_RDONLY))<0)
    20. {
    21. errlog("open error");
    22. }
    23. if((fdw = open(argv[2],O_CREAT|O_WRONLY|O_TRUNC,0664))<0)
    24. {
    25. errlog("open error");
    26. }
    27. if(pipe(fd)<0) //创建管道
    28. {
    29. errlog("pipe error");
    30. }
    31. pid = fork(); //创建父子进程
    32. if(pid<0)
    33. {
    34. errlog("fork error");
    35. }
    36. else if(pid>0){ //父进程
    37. while((nbyte = read(fdr,buf,N))>0) //父进程读取文件写入管道
    38. write(fd[1],buf,nbyte);
    39. printf("读取成功\n");
    40. }
    41. else if(pid==0) //子进程
    42. {
    43. while((nbyte = read(fd[0],buf,N))>0) //子进程从管道中读取,写入文件
    44. write(fdw,buf,nbyte);
    45. }
    46. return 0;
    47. }

    运行:

    对.c文件编译

    ./编译生成.o文件 源文件 目标文件

    cat 目标文件(查看复制后的结果)

    执行成功

  • 相关阅读:
    416. 分割等和子集
    获取街道、乡镇级的地图geoJson数据,使用echarts绘制地图
    代码大全阅读随笔(六)
    JVM常用的一些参数
    使用 snappyjs 压缩数据并解压
    小程序action-sheet结合自定义tabbar显示
    强化学习
    操作系统复习:进程间通信与常见IPC问题
    2024年第16周技术复盘
    基础复习——数据库SQLite——SQL的基本语法——数据库管理器SQLiteDatabase——数据库帮助器SQLiteOpenHelper...
  • 原文地址:https://blog.csdn.net/bujianzingguang/article/details/134466899