Linux 无名管道实现文件复制

无名管道

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

创建无名管道

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

无名管道操作特性

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

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

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

如:write(fd1,buf,nbyte);

read(fd0,buf,N);

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

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

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

fork函数

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

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

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

cs 复制代码
  if(pid>0){                  //父进程
                while((nbyte = read(fdr,buf,N))>0)    //父进程读取文件写入管道
                        write(fd[1],buf,nbyte);
                        printf("读取成功\n");
        }
  if(pid==0)             //子进程
        {
                while((nbyte = read(fd[0],buf,N))>0)  //子进程从管道中读取,写入文件
                        write(fdw,buf,nbyte);

        }

源码:

cs 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/fcntl.h>
#include<error.h>

#define N 128
#define errlog(errmsg) do{perror(errmsg);\
                                printf("--%s--%s--%d--\n",\
                                __FILE__,__FUNCTION__,__LINE__);\
                                return -1;}while(0)

int main(int argc,char *argv[])
{
        pid_t pid;
        int fdr,fdw;
        ssize_t nbyte;
        int fd[2];
        char buf[N] = " ";

        if((fdr = open(argv[1],O_RDONLY))<0)
        {
                errlog("open error");
        }
        if((fdw = open(argv[2],O_CREAT|O_WRONLY|O_TRUNC,0664))<0)
        {
                errlog("open error");
        }

        if(pipe(fd)<0)       //创建管道
        {
                errlog("pipe error");
        }

        pid = fork();       //创建父子进程

        if(pid<0)
        {
                errlog("fork error");
        }
        else if(pid>0){                  //父进程
                while((nbyte = read(fdr,buf,N))>0)    //父进程读取文件写入管道
                        write(fd[1],buf,nbyte);
                        printf("读取成功\n");
        }
        else if(pid==0)             //子进程
        {
                while((nbyte = read(fd[0],buf,N))>0)  //子进程从管道中读取,写入文件
                        write(fdw,buf,nbyte);

        }
        return 0;
}

运行:

对.c文件编译

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

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

执行成功

相关推荐
lsh曙光2 小时前
延时at指令和定时cron指令
linux·服务器·网络
圆山猫2 小时前
[Virtualization](四):Linux KVM/RISC-V 的 vCPU 运行路径
java·linux·risc-v
似的8353 小时前
一步一步学习使用FireMonkey动画() 使用TAnimator类创建动画
linux·学习·nginx
我不管我就要叫小猪4 小时前
嵌入式Linux----网络通信
linux·运维·服务器
泡沫冰@5 小时前
ECS 的介绍和使用
linux·服务器·网络
姜太小白5 小时前
【Linux】df -h 卡住问题的通用排查与解决方案总结
linux·运维·php
fengyehongWorld6 小时前
Linux 终端快捷键
linux·运维
哎呦喂我去去去6 小时前
C#实现屏幕墙:同时监控多个电脑桌面(支持Windows、信创Linux、银河麒麟、统信UOS)
linux·windows·c#
easy_coder8 小时前
Linux LVM 知识文档
linux·运维
小小的木头人8 小时前
Ubuntu 使用 udev + systemd + UUID 实现 USB 硬盘自动挂载
linux·运维·ubuntu