红联Linux门户
Linux帮助

【Linux】利用管道在进程通讯拷贝文件

发布时间:2016-12-20 10:25:43来源:linux网站作者:yongh701
其实Linux-C拷贝文件根本不用这么折腾,具体参见《【Linux】利用C语言文件流复制单一文件》(http://www.linuxdiyf.com/linux/17721.html),这个程序也没有什么卵用,直接一个cp好了,主要是借这个程序说明《【Linux】管道的Helloworld》(http://www.linuxdiyf.com/linux/26949.html)的原理。
 
程序代码如下:
#include <stdio.h>  
#include <stdlib.h>  
#include <unistd.h>//管道所在的头文件
#include <string.h>//用来测定字体长度strlen()的头文件
#define MAX_LINE 1024//设置缓冲区的大小
int main(int argc,char* argv[]){
if(argv[1]==NULL||argv[1]==NULL){
printf("请输入两个文件路径,第一个为源,第二个为目的!\n");
exit(1);
}
char* source_path=argv[1];//取用户输入的第一个参数
char* destination_path=argv[2];//取用户输入的第二个参数  
FILE *in,*out;//定义两个文件流,分别用于文件的读取和写入int len;
if((in=fopen(source_path,"r"))==NULL){//打开源文件的文件流
printf("源文件不存在,请检查路径输入是否存在!\n");
exit(1);
}
if((out=fopen(destination_path,"w"))==NULL){//打开目标文件的文件流
printf("创建目标文件流失败!\n");
exit(1);
}  
char buffer[MAX_LINE+1];  
int myPipe[2];  
int len;//记录读取与写入长度  
if(pipe(myPipe)==0){//创建管道  
pid_t fpid=fork();
if(fpid<0){   
printf("创建父子进程失败!");
}
else if(fpid==0){ 
while((len=fread(buffer,1,MAX_LINE,in))>0){  
write(myPipe[1],buffer,len);//对管道写入读到的文件东西  
}   
}  
else{
int len=read(myPipe[0],buffer,MAX_LINE);//将管道的东西读到缓冲区  
fwrite(buffer,1,len,out);//将缓冲区的数据写到目标文件中  
printf("复制成功完成!\n");
}  
waitpid(fpid,NULL,0);
fclose(out);
fclose(in);   
//一般管道的管道的开启与关闭成轴对称
close(myPipe[0]);
close(myPipe[1]);   
return 0;  
}
 
主要是完成从文件夹a的1.txt复制到文件夹b的操作,运行结果如下图:
【Linux】利用管道在进程通讯拷贝文件
 
在《【Linux】fork()》(http://www.linuxdiyf.com/linux/27062.html)提到通过fork()创建的父子进程是不能同时操作一个变量的。通过Linux的管道可以让父子进程实现变量共享,也就是所谓的“线程同步”。因为子进程要等待父进程的读才能写。整个程序的结构,具体如下图所示:
【Linux】利用管道在进程通讯拷贝文件
估计通过上述的流程图大家就一目了然了,其实程序也本身没什么好说的,就是父进程从旧文件读入数据,写入管道,然后子进程读管道的数据写到新文件。
 
需要提一下的就是,这里读写数据,需要通过一个字符数组接着,以便于进一步操作,这个字符数组buffer也就是所谓的“缓冲区”。都不知道是谁给他这样的一个名称的,反正在“流”的操作中,很常用。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/27064.html