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

执行成功

相关推荐
AlfredZhao28 分钟前
用 crontab 给 LLM 使用量装上“监控眼”
linux
刃神太酷啦3 小时前
Linux 系统 MySQL 完整安装配置教程:从卸载 MariaDB 到优化 my.cnf----《Hello MySQL!》(1)
android·linux·c语言·c++·mysql·leetcode·mariadb
赵文宇(温玉)4 小时前
OpenEuler24.03 SP4 系统安装(欧拉/麒麟V10)
linux·openeuler·欧拉
Brilliantwxx5 小时前
【Linux】 进程(7)深度剖析 进程内核O(1)调度队列 + 饥饿问题
linux·运维·服务器
刚入门的大一新生6 小时前
Linux-命令行参数和环境变量
linux·运维·服务器
我星期八休息7 小时前
Linux I/O多路转接—epoll
java·linux·运维·服务器·开发语言·jvm·算法
wuminyu7 小时前
Java FFM处理网络读写事件源码剖析
java·linux·c语言·jvm·c++
实心儿儿8 小时前
Linux —— 数据链路层
linux·网络·智能路由器
智购科技无人售货机厂家8 小时前
2026自动售货机出货口防夹手设计:从红外检测到电机反转的工程实践~YH
大数据·linux·单片机·嵌入式硬件·微信
新时代牛马9 小时前
异常向量与VBAR_ELx:Linux entry.S 中的vectors 布局
linux·运维·服务器