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(一定大于零的整数),子进程同样得到一个返回值但为零。

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

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

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 目标文件(查看复制后的结果)

执行成功

相关推荐
utf8mb4安全女神2 小时前
Linux网络服务
linux·运维·服务器
vortex52 小时前
Linux PAM 配置详解:从原理到实战,彻底阻断非授权提权
java·linux·服务器
ZPC82102 小时前
Linux Preempt-RT 实时内核 ** 抖动(Jitter)** 完整测试方法
linux·运维·服务器
2501_920047032 小时前
openclaw在ubuntu系统的安装
linux·运维·ubuntu·openclaw
一个人旅程~3 小时前
linux如何“抢”过windows的usb移动硬盘权限对0磁道损坏的移动硬盘进行尝试修复
linux·windows·经验分享·电脑
sukioe4 小时前
Linux RPM 方式安装 MySQL 8.0
linux·mysql·adb
Bert.Cai4 小时前
Linux tee命令详解
linux·运维·服务器
宋浮檀s5 小时前
应急响应(系统日志)
linux·运维·网络安全·应急响应
cui_ruicheng5 小时前
Linux网络编程(七):TCP Socket编程与EchoServer
linux·服务器·网络·tcp/ip
feasibility.6 小时前
nvidia-smi 失灵,显存凭空消失?—— NVML 驱动版本错配的记录
linux·运维·服务器·经验分享·nvidia·驱动