我发现 Files.isSameFile 只比较路径字符串。
不完全是。 Javadoc 说:
如果两个 Path 对象相等,则此方法返回 true
检查文件是否存在。如果两个 Path 对象关联
使用不同的提供者,则此方法返回 false。否则,
此方法检查两个 Path 对象是否找到相同的文件,并且
根据实现,可能需要同时打开或访问两者
文件。
方法isSameFile()不比较内容,它是用来定义是否two paths point to the same location in the file system。
如果根据 equals() 方法两个路径相同,则此方法将返回 true。在这种情况下,none of these paths need to exist 用于实数和比较归结为您所说的字符串比较。
如果不是这种情况,它将尝试访问这些路径。
如果它们代表文件系统中的位置,即一个路径是 symbolic link,它指向另一个路径 isSameFile() 将返回 true。
如果他们两个都退出但不相互引导,它将返回false。
如果文件系统中至少有一个不存在,它将引发异常。
public static void main(String[] args) throws IOException {
Path p1 = Paths.get("C:", "a", "b", "c", "test.txt");
Path p2 = Paths.get("C:",".", ".", ".", "FooBar", "..", "a", "b", "c", "test.txt");
Path p3 = p1.resolveSibling(Paths.get("copy.txt")); // path that leads to another file in the same folder
Path copy = Files.copy(p1, p3); // contents of p1 is being coped into p3, path to p3 is returned
System.out.println("Path 'p1': " + p1);
System.out.println("Path 'p2`: " + p2);
System.out.println("Path 'copy': " + copy);
System.out.println("\np1 and p2 are the same: " + Files.isSameFile(p1, p2));
System.out.println("p1 and copy are the same: " + Files.isSameFile(p1, copy));
// Path p4 = Paths.get("C:", "a", "link.txt");
// Path symbolicLink = Files.createSymbolicLink(p4, p1);
// System.out.println("p1 and symbolicLink are the same: " + Files.isSameFile(p1, symbolicLink));
}
处理符号链接的行被注释掉,因为它不能以如此直接的方式完成。 Symbolik 链接可能会引入漏洞,系统将不允许 JVM 执行此操作。但是如果我们假设有一个指向 p1 的符号链接,那么Files.isSameFile(p1, symbolicLink) 将返回 true
输出
Path 'p1': C:\a\b\c\test.txt
Path 'p2`: C:\.\.\.\FooBar\..\a\b\c\test.txt
Path 'copy': C:\a\b\c\copy.txt
p1 and p2 are the same: true
p1 and copy are the same: false
文件内容比较
对于apart from Files.mismatch() 中的compare the actual contents 文件,可以使用最新的Java 长期支持版本访问only ,您可以创建自己的方法来查找文件之间的差异,如下所示:
public static boolean compareFiles(Path p1, Path p2) throws IOException {
boolean isSameFile = true;
try (var input1 = new BufferedInputStream(Files.newInputStream(p1));
var input2 = new BufferedInputStream(Files.newInputStream(p2))) {
byte[] buffer1 = new byte[1024];
byte[] buffer2 = new byte[1024];
int bytesRead1 = -1;
int bytesRead2 = -1;
while (isSameFile && bytesRead1 != 0 && bytesRead2 != 0) {
bytesRead1 = input1.readNBytes(buffer1, 0, buffer1.length);
bytesRead2 = input2.readNBytes(buffer2, 0, buffer2.length);
if (!Arrays.equals(buffer1, buffer2)) {
isSameFile = false;
}
}
}
return true;
}