C语言使用管道复制文件时缓冲区残留字符问题求助
解决管道文件复制时缓冲区残留字符的问题
嘿,我来帮你搞定这个问题!你遇到的末尾残留字符的问题,核心原因很明确:你每次都固定写入10字节,但最后一次读取到的字节数其实小于10,这时候缓冲区里之前留下的旧数据就被一起写到目标文件里了,所以才会多出那个“p”,导致MD5校验不一致。
关键修复思路
解决这个问题的核心就是不要固定读写10字节,而是根据每次read的实际返回值来决定写入的字节数:
- 每次调用
read后,保存它的返回值(这个值就是实际读取到的字节数,返回0表示文件读取完毕,返回-1表示出错) - 写入的时候,用这个实际读取的字节数作为写入长度,而不是硬写10字节
修改后的完整代码
我把你的代码做了针对性修改,标注了关键改动点:
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { int fd[2]; char message[10]; // 10字节缓冲区 int filefd; // 创建管道(补上你代码中可能遗漏的管道初始化) if (pipe(fd) == -1) { perror("pipe failed"); exit(EXIT_FAILURE); } // ====== 写者部分(读取in.txt,写入管道)====== filefd = open(argv[1], O_RDONLY, 0); if (filefd == -1) { perror("open input file failed"); exit(EXIT_FAILURE); } ssize_t bytes_read; // 用ssize_t存储read返回值,支持负数错误码 int i = 0; // 循环读取文件,直到read返回0(结束)或-1(错误) while ((bytes_read = read(filefd, message, 10)) > 0) { // 用%.*s指定打印长度,避免输出缓冲区垃圾字符 printf("writer: msg%d=%.*s\n", i+1, (int)bytes_read, message); fflush(stdout); // 关键:写入实际读取的字节数,而非固定10 write(fd[1], message, bytes_read); usleep(100000); i++; } // 检查read是否出错 if (bytes_read == -1) { perror("read input file failed"); exit(EXIT_FAILURE); } close(filefd); close(fd[1]); // 写完管道后关闭写端,让读端知道数据已结束 // ====== 读者部分(读取管道,写入out.txt)====== filefd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666); if (filefd == -1) { perror("open output file failed"); exit(EXIT_FAILURE); } i = 0; while ((bytes_read = read(fd[0], message, 10)) > 0) { printf("reader: msg%d=%.*s\n", i+1, (int)bytes_read, message); fflush(stdout); // 同样:写入实际读取的字节数 write(filefd, message, bytes_read); usleep(120000); i++; } if (bytes_read == -1) { perror("read pipe failed"); exit(EXIT_FAILURE); } close(filefd); close(fd[0]); return 0; }
额外说明
- 关于
ssize_t:这个类型专门用来存储系统调用的返回值,它可以表示负数(错误)、0(结束)和正整数(实际字节数),比int更适配这类场景。 - 关于
%.*s:这个格式符的作用是按指定长度打印字符串,避免打印缓冲区里未被覆盖的垃圾字符(比如之前残留的“p”),让调试输出更准确。 - 关闭管道端点:写完管道后一定要关闭写端,这样读端的
read才会在数据读完后返回0,否则读端会一直阻塞等待数据。
修改后再运行程序,目标文件out.txt的内容就会和in.txt完全一致,MD5校验结果也会相同啦!
内容的提问来源于stack exchange,提问作者Szymon 呕ak
相关产品推荐
相关产品推荐

