我发现了这个
Files.mismatch()
方法来比较两个文件的原始字节数据并检查它们是否完全相等,即它们是否是彼此的重复文件。
您知道在非常大的文件(GB 数量级)上使用此方法是否会出现任何问题吗?并且,它适用于所有文件类型吗?我相信这两点不会有任何问题,但只是为了确定一下。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class finding_duplicates {
public static void main(String args[]) throws IOException{
Path filePath1 = Path.of(/*[...]/Desktop/test1.[any extension you like]"*/);
Path filePath2 = Path.of(/*[...]/Desktop/test2.[any extension you like]"*/);
long mis_match = Files.mismatch(filePath1, filePath2);
if (mis_match == -1){System.out.println("files are equal");}
else{System.out.println("files are different");}
}
}
这里是 JDK 17 的 Eclipse temurin 实现中方法 mismatch 的源代码。如您所见,它以字节流的形式读取两个文件,这意味着它可以处理任何类型的文件。由于变量
totalRead
是 long
,因此如果文件大小大于 [constant] MAX_VALUE(在类 java.lang.Long
中),该方法可能无法正常工作。请注意,
MAX_VALUE
超过 9 个exabytes,因此我认为您无需担心文件大小。
public static long mismatch(Path path, Path path2) throws IOException {
if (isSameFile(path, path2)) {
return -1;
}
byte[] buffer1 = new byte[BUFFER_SIZE];
byte[] buffer2 = new byte[BUFFER_SIZE];
try (InputStream in1 = Files.newInputStream(path);
InputStream in2 = Files.newInputStream(path2);) {
long totalRead = 0;
while (true) {
int nRead1 = in1.readNBytes(buffer1, 0, BUFFER_SIZE);
int nRead2 = in2.readNBytes(buffer2, 0, BUFFER_SIZE);
int i = Arrays.mismatch(buffer1, 0, nRead1, buffer2, 0, nRead2);
if (i > -1) {
return totalRead + i;
}
if (nRead1 < BUFFER_SIZE) {
// we've reached the end of the files, but found no mismatch
return -1;
}
totalRead += nRead1;
}
}
}
您知道在非常大的文件(千兆字节数量级)上使用此方法是否会出现任何问题吗?
一个问题是
mismatch
需要很长时间才能读取和比较千兆字节级别的文件。
您可以采取一些措施来解决这个问题。由于您只关心文件是否不同...而不是差异在哪里...您可以从比较文件的大小开始。如果两个文件的大小不同,它们就会不同。
它适用于所有文件类型吗?
嗯……是的。在您比较这些文件的级别,只有一种类型:字节数组。