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

执行成功

相关推荐
用户31187945592187 小时前
Kylin Linux 10 安装 glib2-devel-2.62.5-7.ky10.x86_64.rpm 方法(附安装包)
linux
涛啊涛7 小时前
Centos7非LVM根分区容量不足后扩容,对调硬盘挂载/
linux·磁盘管理
CYRUS_STUDIO1 天前
用 Frida 控制 Android 线程:kill 命令、挂起与恢复全解析
android·linux·逆向
熊猫李1 天前
rootfs-根文件系统详解
linux
dessler1 天前
Hadoop HDFS-高可用集群部署
linux·运维·hdfs
泽泽爱旅行1 天前
awk 语法解析-前端学习
linux·前端
轻松Ai享生活2 天前
5 节课深入学习Linux Cgroups
linux
christine-rr2 天前
linux常用命令(4)——压缩命令
linux·服务器·redis
三坛海会大神5552 天前
LVS与Keepalived详解(二)LVS负载均衡实现实操
linux·负载均衡·lvs
東雪蓮☆2 天前
深入理解 LVS-DR 模式与 Keepalived 高可用集群
linux·运维·服务器·lvs