使用无名管道传输数据:基于read()/write()/open()的文件读写需求
无名管道实现文件内容传输的完整代码实现
我帮你补全并优化了符合需求的完整代码,完全遵循你的要求——使用无名管道传输字节数据,依赖open()、read()、write()这些系统调用完成input.txt到output.txt的内容传输,同时加入了必要的错误处理逻辑,避免程序异常崩溃:
#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/wait.h> #define BUFFER_SIZE 1024 // 定义每次读写的缓冲区大小 int main() { int pipe_fd[2]; pid_t pid; char buffer[BUFFER_SIZE]; ssize_t bytes_read, bytes_written; // 创建无名管道 if (pipe(pipe_fd) == -1) { perror("pipe creation failed"); exit(EXIT_FAILURE); } // 创建子进程 pid = fork(); if (pid == -1) { perror("fork failed"); exit(EXIT_FAILURE); } if (pid == 0) { // 子进程:从管道读数据,写入output.txt close(pipe_fd[1]); // 子进程不需要写端,关闭它 // 打开output.txt,不存在则创建,存在则清空内容 int output_fd = open("output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); if (output_fd == -1) { perror("open output.txt failed"); close(pipe_fd[0]); exit(EXIT_FAILURE); } // 循环从管道读取数据,直到读完全部内容 while ((bytes_read = read(pipe_fd[0], buffer, BUFFER_SIZE)) > 0) { // 将读取到的数据写入output.txt,确保全部写入 bytes_written = write(output_fd, buffer, bytes_read); if (bytes_written != bytes_read) { perror("write to output.txt failed"); close(output_fd); close(pipe_fd[0]); exit(EXIT_FAILURE); } } if (bytes_read == -1) { perror("read from pipe failed"); } // 关闭文件描述符 close(output_fd); close(pipe_fd[0]); exit(EXIT_SUCCESS); } else { // 父进程:读取input.txt,写入管道 close(pipe_fd[0]); // 父进程不需要读端,关闭它 // 打开input.txt,只读模式 int input_fd = open("input.txt", O_RDONLY); if (input_fd == -1) { perror("open input.txt failed"); close(pipe_fd[1]); exit(EXIT_FAILURE); } // 循环读取input.txt内容,直到读完全部 while ((bytes_read = read(input_fd, buffer, BUFFER_SIZE)) > 0) { // 将读取到的数据写入管道,确保全部写入 bytes_written = write(pipe_fd[1], buffer, bytes_read); if (bytes_written != bytes_read) { perror("write to pipe failed"); close(input_fd); close(pipe_fd[1]); exit(EXIT_FAILURE); } } if (bytes_read == -1) { perror("read from input.txt failed"); } // 关闭文件描述符,通知子进程管道已无数据 close(input_fd); close(pipe_fd[1]); // 等待子进程完成 wait(NULL); exit(EXIT_SUCCESS); } }
关键细节说明
- 管道操作:无名管道的
pipe_fd[0]是读端,pipe_fd[1]是写端;父进程关闭读端,子进程关闭写端,避免管道出现不必要的阻塞。 - 循环读写:使用
while循环处理读写操作,因为read()和write()不一定能一次性处理全部数据,必须根据返回值判断是否完成。 - 错误处理:每个系统调用(
pipe()、fork()、open()、read()、write())都加入了错误检查,确保程序在异常情况下能给出明确提示并安全退出。 - 文件权限:创建
output.txt时设置了0644权限,保证文件能被正常读取和修改。
编译运行的话,直接用gcc编译:
gcc pipe_transfer.c -o pipe_transfer ./pipe_transfer
运行前确保input.txt存在,运行后就能在output.txt看到和input.txt完全一致的内容了。
内容的提问来源于stack exchange,提问作者Taknie
相关产品推荐
相关产品推荐

