C语言判断两文件内容是否相同的算法出错,求排查原因
文件比较函数误判内容不一致的原因
你的代码触发memcmp返回非零的核心问题有两个:
缓冲区未读取区域的垃圾数据干扰
当文件剩余字节数小于BYTES_TO_READ_AT_ONCE时,fread只会填充缓冲区的前N个字节(N为实际读取的字节数),缓冲区剩余部分是栈上的随机垃圾数据。你用memcmp比较整个缓冲区的大小,两个缓冲区的垃圾数据几乎不可能相同,因此会错误判定文件内容不一致。未校验第二个文件的读取结果
你只判断了第一个文件的fread返回值,没有验证第二个文件的读取是否成功或读取字节数是否匹配。如果第二个文件读取出现异常,databuffer2会包含无效数据,同样会导致memcmp误判。
修复后的代码
int are_files_equal(char* filename1, char* filename2){ if(strcmp(filename1, filename2) == 0) return 1; struct stat stat1, stat2; if (stat(filename1, &stat1) != 0 || stat(filename2, &stat2) != 0) return -1; // 获取文件元信息失败 if(stat1.st_size != stat2.st_size) return 0; // 文件大小不同,直接判定不一致 FILE *file1 = fopen(filename1, "rb"); FILE *file2 = fopen(filename2, "rb"); if (file1 == NULL || file2 == NULL) { // 避免资源泄漏,关闭已成功打开的文件 if (file1) fclose(file1); if (file2) fclose(file2); return -1; // 打开文件失败 } #define BYTES_TO_READ_AT_ONCE 512000 unsigned char databuffer1[BYTES_TO_READ_AT_ONCE]; unsigned char databuffer2[BYTES_TO_READ_AT_ONCE]; size_t bytes_read1, bytes_read2; while ((bytes_read1 = fread(databuffer1, 1, BYTES_TO_READ_AT_ONCE, file1)) != 0) { // 读取与第一个文件相同字节数的数据 bytes_read2 = fread(databuffer2, 1, bytes_read1, file2); // 校验读取结果+内容一致性 if (bytes_read2 != bytes_read1 || memcmp(databuffer1, databuffer2, bytes_read1) != 0) { fclose(file1); fclose(file2); return 0; } } // 额外校验第二个文件是否也已读取完毕(防范IO异常导致的进度不一致) bytes_read2 = fread(databuffer2, 1, 1, file2); if (bytes_read2 != 0) { fclose(file1); fclose(file2); return 0; } fclose(file1); fclose(file2); return 1; }
关键修复点
- 用实际读取的字节数作为
memcmp的比较长度,避免垃圾数据干扰。 - 同步两个文件的读取字节数,并校验读取结果是否一致。
- 循环结束后校验第二个文件的读取状态,排除IO异常导致的进度偏差。
- 增加资源泄漏防护:打开文件失败时关闭已打开的文件。
内容的提问来源于stack exchange,提问作者Alessandro
相关产品推荐
相关产品推荐

