二进制文件读写后内容不一致,求问题原因及解决方法
问题原因分析
你的代码核心问题出在fread和fwrite的参数使用逻辑错误,导致读取与写入的数据不符合预期:
fread(buffer, sizeof(buffer), 1, in):该调用的含义是尝试读取1个大小等于整个buffer的块(即1000000个unsigned int,总字节数为4MB)。只有当原文件file.bin的大小恰好等于4MB时,才能完整读取所有内容;若原文件小于4MB,fread会读取失败(返回0),但你依然会把整个buffer(包括未初始化的垃圾数据)写入out.bin;若原文件大于4MB,只能读取前4MB内容,剩余部分被丢弃,写入的还是4MB数据,最终导致两个文件内容不一致。- 后续的
fwrite(buffer, sizeof(buffer), 1, out)同样是将整个buffer的内容全部写入,完全忽略了实际成功读取的数据量,进一步放大了问题。
修复方案
正确的做法是按字节读取,记录实际读取的字节数,再写入对应数量的数据,同时需要检查文件是否成功打开:
#include <stdio.h> int main() { // 用unsigned char处理二进制文件更合适,与字节流一一对应 unsigned char buffer[1000000]; size_t read_size; FILE *in = fopen("file.bin", "rb"); if (!in) { // 检查输入文件是否打开成功 perror("Failed to open input file"); return 1; } // 按字节读取,最多读取buffer的总容量,返回实际读取的字节数 read_size = fread(buffer, 1, sizeof(buffer), in); fclose(in); FILE *out = fopen("out.bin", "wb"); if (!out) { // 检查输出文件是否打开成功 perror("Failed to open output file"); return 1; } // 仅写入实际读取到的字节数 fwrite(buffer, 1, read_size, out); fclose(out); return 0; }
额外补充两点注意事项:
- 使用
unsigned char作为buffer类型更适配二进制文件操作,它的宽度为1字节,能和文件的字节流完全对应,避免unsigned int(通常4字节)带来的对齐或拆分问题。 - 必须检查
fopen的返回值,防止文件打开失败后执行后续操作引发的错误。
内容的提问来源于stack exchange,提问作者Ben McDonald
相关产品推荐
相关产品推荐

