You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用无名管道传输数据:基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:48:55