【发布时间】:2018-01-24 08:38:09
【问题描述】:
我需要比较两个文件。一个文件可能比另一个文件长,我需要检查较长的文件是否包含较短文件的所有数据。 我可以对两者进行二进制比较,如下所示:
function compareFiles($file_a, $file_b){
if (filesize($file_a) > filesize($file_b)){
$fp_a = fopen($file_b, 'rb');
$fp_b = fopen($file_a, 'rb');
} else { // filesize($file_b) > filesize($file_a)
$fp_a = fopen($file_a, 'rb');
$fp_b = fopen($file_b, 'rb');
}
while (($b = fread($fp_a, 4096)) !== false){
$b_b = fread($fp_b, 4096);
if ($b !== $b_b){
fclose($fp_a);
fclose($fp_b);
return false;
}
}
fclose($fp_a);
fclose($fp_b);
return true;
}
但这会很慢。作为替代方案,我可以将较小文件的 SHA1 哈希值与较大文件的 SHA1 哈希值进行比较,直到较小文件的大小,如下所示:
function compareFiles($file_a, $file_b){
$tmpfile = '/dev/shm/tmp_file_copy.bin';
if (filesize($file_a) > filesize($file_b)){
$readfromfile = $file_b;
$bytes_to_copy = filesize($file_b);
} else {
$readfromfile = $file_a
$bytes_to_copy = filesize($file_a);
}
$readfile = fopen($readfromfile, 'rb');
$writefile = fopen($tmpfile, 'wb');
while (!feof($readfile) && $bytes_to_copy> 0) {
if ($bytes_to_copy <= 8192) {
$contents = fread($readfile, $bytes_to_copy);
$bytes_to_copy = 0;
} else {
$contents = fread($readfile, 8192);
$bytes_to_copy =- 8192;
}
fwrite($writefile, $contents);
}
fclose($writefile);
fclose($readfile);
$result = sha1_file($readfromfile = $file_a ? $file_b : $file_a) === sha1_file($tmpfile);
unlink($tmpfile);
return $result;
}
但我担心这也会很慢,因为它涉及大量 I/O(到 /dev/shm)。
简而言之,我正在寻找更好的方法......
【问题讨论】:
-
比较所需的输出是什么?
-
输出是真还是假。不超过较短文件长度的文件内容匹配或不匹配。
-
您可以使用 fread 将整个文件获取到字节 X 以进行比较,您不需要将其循环成块
-
是的,但在我看来,将其分块更安全。我也可以在那里添加重试,但这会变得更复杂,并从问题的角度误导读者。