# 任务要求
具体要求如下,总计使用两个进程,第一个进程负责把读取文件并写入管道,第二个进程负责读取管道并写入新文件。
# 任务详解
也就是说我需要创建两个进程,那我需要用到 pthread_create 函数,该函数位于 pthread.h 头文件中,其次我还需要创建一个管道记录缓冲数据,这里我选用的是 FIFO 管道,最后再写两个文件复制函数 WriteFile 和 CopyFile, 两个函数大致相同,所以不用过于害怕,而实际其实也挺简单的。
# 程序流程
- 得到读取和写入的文件名字 (字符串类型)
- 创建 FIFO 命名管道
- 创建文件读取的进程
- 创建文件写入的进程
- 销毁进程与管道
# 管道和进程的创建
很简单,核心代码都只需要一句话就行。
#include <pthread.h> | |
// Create a FIFO pipeline | |
mkfifo("FIFO",0666); | |
// Create a Linux process | |
pthread_t tid1, tid2; | |
int ret = pthread_create(&tid1, NULL, CopyFile, src); | |
int wet = pthread_create(&tid2, NULL, WriteFile, target); | |
// Destroy processes and pipes | |
pthread_join(tid1, NULL); | |
pthread_join(tid2, NULL); | |
unlink("FIFO"); |
# 文件的读取与写入
流程大致如下:
- 设置缓冲区
- 打开文件和管道
- 读取文件或管道一定内容并偏移文件读取位置,写入文件或管道的内容,直至文件读取位置至文件末尾。
// Read file data to FIFO pipe | |
void *CopyFile(void *src) | |
{ | |
unsigned char buff[1024]; | |
char* mkfifo = "FIFO"; | |
int rfd = open(src,O_RDONLY); | |
int wrd = open(mkfifo,O_WRONLY, 0666); | |
if(rfd < 0||wrd < 0) | |
{ | |
perror("CopyFile: open file error\n"); | |
exit(1); | |
} | |
lseek(rfd, 0, SEEK_SET); | |
int real_read_len; | |
while((real_read_len = read(rfd, buff, sizeof(buff))) > 0) | |
{ | |
write(wrd, buff, real_read_len); | |
} | |
close(rfd); | |
close(wrd); | |
return 0; | |
} | |
// Read data from FIFO pipe and write to file | |
void *WriteFile(void *target) | |
{ | |
unsigned char buff[1024]; | |
char* mkfifo = "FIFO"; | |
int rfd = open(mkfifo,O_RDONLY); | |
int wrd = open(target,O_WRONLY | O_CREAT, 0666); | |
if(rfd < 0||wrd < 0) | |
{ | |
perror("WriteFile: open file error\n"); | |
exit(1); | |
} | |
lseek(rfd, 0, SEEK_SET); | |
int real_read_len; | |
while((real_read_len = read(rfd, buff, sizeof(buff))) > 0) | |
{ | |
write(wrd, buff, real_read_len); | |
} | |
close(rfd); | |
close(wrd); | |
return 0; | |
} |
# 运行
使用如下命令即可,可惜目前 WSL 不支持 - lpthread 这个参数,你只能去虚拟机或服务器玩了。
gcc -o file filename.c -lpthread | |
./file readfilename writefilename |
# 完整源代码
#include <stdio.h> | |
#include <pthread.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <string.h> | |
#define size 20 | |
void *CopyFile(void *src) | |
{ | |
unsigned char buff[1024]; | |
char* mkfifo = "FIFO"; | |
int rfd = open(src,O_RDONLY); | |
int wrd = open(mkfifo,O_WRONLY, 0666); | |
if(rfd < 0||wrd < 0) | |
{ | |
perror("CopyFile: open file error\n"); | |
exit(1); | |
} | |
lseek(rfd, 0, SEEK_SET); | |
int real_read_len; | |
while((real_read_len = read(rfd, buff, sizeof(buff))) > 0) | |
{ | |
write(wrd, buff, real_read_len); | |
} | |
close(rfd); | |
close(wrd); | |
return 0; | |
} | |
void *WriteFile(void *target) | |
{ | |
unsigned char buff[1024]; | |
char* mkfifo = "FIFO"; | |
int rfd = open(mkfifo,O_RDONLY); | |
int wrd = open(target,O_WRONLY | O_CREAT, 0666); | |
if(rfd < 0||wrd < 0) | |
{ | |
perror("WriteFile: open file error\n"); | |
exit(1); | |
} | |
lseek(rfd, 0, SEEK_SET); | |
int real_read_len; | |
while((real_read_len = read(rfd, buff, sizeof(buff))) > 0) | |
{ | |
write(wrd, buff, real_read_len); | |
} | |
close(rfd); | |
close(wrd); | |
return 0; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
char* src = (char*)malloc(sizeof(char)*size); | |
char* target = (char*)malloc(sizeof(char)*size); | |
strcpy(src,argv[1]); | |
strcpy(target,argv[2]); | |
mkfifo("FIFO",0666); | |
pthread_t tid1, tid2; | |
int ret = pthread_create(&tid1, NULL, CopyFile, src); | |
int wet = pthread_create(&tid2, NULL, WriteFile, target); | |
pthread_join(tid1, NULL); | |
pthread_join(tid2, NULL); | |
// unlink("FIFO"); | |
free(target); | |
free(src); | |
return 0; | |
} |