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

执行成功

相关推荐
looking_for__13 分钟前
【Linux】Ext系列文件系统
linux
OliverH-yishuihan1 小时前
开发linux项目-在 Windows 上 基于“适用于 Linux 的 Windows 子系统(WSL)”
linux·c++·windows
南棱笑笑生3 小时前
20251224给飞凌OK3588-C开发板适配Rockchip原厂的Buildroot【linux-6.1】系统时确认ssh服务【内置dropbear】
linux·c语言·ssh·rockchip
I · T · LUCKYBOOM3 小时前
30.Firewalld-Linux
linux·运维·安全
沙滩小绵羊3 小时前
Linux常见命令
linux·运维·服务器
驰羽3 小时前
NAT模式下VMware的虚拟机DNS解析失败的问题解决
linux·网络·dns
菜鸡00014 小时前
安装G2O
linux
誰能久伴不乏4 小时前
epoll 学习踩坑:`fcntl` 设置非阻塞到底用 `F_SETFL` 还是 `F_SETFD`?
linux·服务器·网络·c++·tcp/ip
来鸟 鸣间5 小时前
MIPI D-PHY 理解
linux·音视频·sensor·mipi
么么...5 小时前
在 Ubuntu 上安装 Docker 并部署 MySQL 容器
linux·运维·经验分享·笔记·mysql·ubuntu·docker