这是解决方案,一个字符一个字符的读取/比较(灵感来自 myxaxa 的答案,但有错误修复)和另一个逐块读取/比较。由于懒惰,错误检查已被跳过,但一个健壮的实现必须有错误检查。(看评论)
#include <stdio.h>
int main(int argc, char **argv)
{
int equal = 1;
// TODO: check argc == 3
FILE *data_1 = fopen(argv[1],"r");
FILE *data_2 = fopen(argv[2],"r");
// TODO: check data_1 and data_2 !=NULL
for (;;)
{
int ch1, ch2;
ch1 = fgetc(data_1);
ch2 = fgetc(data_2);
if (ch1 != ch2)
{
equal = 0;
break;
}
// We only need to test ch1, because at this point ch1 == ch2;
if (ch1 == EOF)
break;
}
// TODO: check for read errors in data_1 and data_2 using ferror
fclose(data_1);
fclose(data_2);
if (equal)
printf("equal\n");
else
printf("not equal\n");
}
使用块读取/比较的第二种解决方案:
#include <stdio.h>
#include <string.h>
#define BUFFSIZE 4096
int main(int argc, char **argv)
{
int equal = 1;
// TODO: check argc == 3
FILE *data_1 = fopen(argv[1],"r");
FILE *data_2 = fopen(argv[2],"r");
// TODO: check data_1 and data_2 !=NULL
for (;;)
{
char b1[BUFFSIZE];
char b2[BUFFSIZE];
size_t r1 = fread(b1, 1, BUFFSIZE, data_1);
size_t r2 = fread(b2, 1, BUFFSIZE, data_2);
if (r1 != r2)
{
equal = 0;
break;
}
// We only need to test r1, because at this point r1 == r2;
if (r1 == 0)
break;
if (memcmp(b1, b2, r1) != 0)
{
equal = 0;
break;
}
}
// TODO: check for read errors in data_1 and data_2 using ferror
fclose(data_1);
fclose(data_2);
if (equal)
printf("equal\n");
else
printf("not equal\n");
}
与自身相比,840Mb 文件上的 char by char 读取/比较的运行时间:
real 0m5.158s
user 0m4.880s
sys 0m0.277s
...并在同一个文件上逐块:
real 0m0.353s
user 0m0.083s
sys 0m0.270s
两个测试都进行了多次运行以确保文件已被缓存