1、实验目的
通过有名管道实现将一个文件中的内容拷贝到另一个文件中
2、实验要求
包括三个文件:
1、mkfifo.c:创建管道文件fifo
2、reader.c:从终端argv[1]所指定的文件中读取内容,写入到管道文件fifo中
3、writer.c:从管道文件fifo中读取内容,写到argv[1]所指定的文件中并保存
3、所需函数
(1)、创建管道文件——mkfifo()
头文件:
#include <sys/types.h>
#include <sys/stat.h>函数原型:
int mkfifo(const char *pathname, mode_t mode);
参数:
pathname:创建管道文件的文件名
mode:创建管道文件的权限,一般为0664
返回值:成功返回0,失败返回1
(2)、文件IO打开文件——open
头文件:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);参数:
pathname:打开文件的文件名(包含路径)
flags:打开文件的方式
O_RDONLY:以只读方式打开文件
O_WRONLY:以只写方式打开文件
O_RDWR:以读写方式打开文件
以上三个选项必须选一个进行操作
O_CREAT:当打开文件不存在时,用该选项创建新文件,并用第三个参数为其设置权限
O_EXCL:一般和O_CREAT联合使用,用于检测文件是否存在
O_APPEND:以追加方式打开文件,在文件末尾另起一行继续写入
O_TRUNC:打开文件之后会将原文件清空
mode:
当需要创建新文件时,需要用该参数给新建文件设置初始权限,一般设置为0664
返回值:
成功返回文件描述符,失败返回-1;
(3)、文件读出函数——read()
头文件:
#include <unistd.h>
函数原型:
ssize_t read(int fd, void *buf, size_t count);
参数:
fd:读取文件的文件描述符
buf:用户自定义的缓冲区,用于存放读取的内容
count:请求读取的字节数
返回值:
成功返回读取的字节数,失败返回-1,返回0表示读到文件末尾;
(4)、文件写入函数——write()
头文件:
#include <unistd.h>
函数原型:
ssize_t write(int fd, const void *buf, size_t count);
参数:
fd:读取文件的文件描述符
buf:用户自定义的缓冲区,用于存放准备写入的内容
count:请求写入的字节数
返回值:
成功返回写入的字节数,失败返回-1;
(5)、文件关闭函数——close()
头文件:
#include <unistd.h>
函数原型:
int close(int fd);
参数:
fd:要关闭文件的文件描述符
返回值:
成功返回0,失败返回-1
4、代码实现
(1)、创建管道文件——mkfifo.c
/*===============================================================
* Copyright (C) 2022 All rights reserved.
*
* 文件名称:mkfifo.c
* 创 建 者:QiuCC
* 创建日期:2022年08月13日
* 描 述:
*
* 更新日志:
*
================================================================*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <strings.h>
#define N 100
int main(int argc, char *argv[])
{
int ret = mkfifo("fifo", 0664);
if(ret == -1){
perror("mkfifo");
exit(-1);
}
return 0;
}
(2)、创建reader.c文件
/*===============================================================
* Copyright (C) 2022 All rights reserved.
*
* 文件名称:reader.c
* 创 建 者:QiuCC
* 创建日期:2022年08月13日
* 描 述:
*
* 更新日志:
*
================================================================*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 100
int main(int argc, char *argv[])
{
if(argc != 2){
printf("请输入 ./a.out <dst_name>\n");
exit(-1);
}
int fd1 = open("fifo", O_WRONLY);
if(fd1 == -1){
perror("open fifo");
exit(-1);
}
int fd2 = open(argv[1], O_RDONLY);
if(fd2 == -1){
perror("open argv[1]");
exit(-1);
}
while(1){
char str[N] = {0};
int ret = read(fd2, str, N);
write(fd1, str, strlen(str));
puts(str);
if(ret == 0){
break;
}
}
close(fd1);
close(fd2);
return 0;
}
(3)、创建write.c文件
/*===============================================================
* Copyright (C) 2022 All rights reserved.
*
* 文件名称:write.c
* 创 建 者:QiuCC
* 创建日期:2022年08月13日
* 描 述:
*
* 更新日志:
*
================================================================*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 100
int main(int argc, char *argv[])
{
if(argc != 2){
printf("请输入 ./a.out <dst_name>\n");
exit(-1);
}
int fd1 = open("fifo", O_RDONLY);
if(fd1 == -1){
perror("open fifo");
exit(-1);
}
int fd2 = open(argv[1], O_WRONLY);
if(fd2 == -1){
perror("open argv[1]");
exit(-1);
}
while(1){
char str[N] = {0};
int ret = read(fd1, str, N);
if(ret == -1){
perror("read");
exit(-1);
}
puts(str);
write(fd2, str, strlen(str));
if(ret == 0){
break;
}
}
close(fd1);
close(fd2);
return 0;
}
5、结果展示和分析
以下就是我们运行程序之后的文件目录下的具体情况了!
1、编译运行mkfifo
2、编译运行reader和write,由于为管道通信,所以我们只有同事运行reader和write可执行文件才可以完成相应的文件操作。
![]()
好的,以上就是今天的内容啦!!!
欢迎大家参考指正!!!
记得三连!!!