Java文件等于
我不知道你们的情况,但至少我认为f1在下面的代码中等于f2,但显然不是这样!你对此有什么想法?似乎我必须写我自己的equals方法来支持它,对吗Java文件等于,java,file,compare,equals,Java,File,Compare,Equals,我不知道你们的情况,但至少我认为f1在下面的代码中等于f2,但显然不是这样!你对此有什么想法?似乎我必须写我自己的equals方法来支持它,对吗 import java.io.*; public class FileEquals { public static void main(String[] args) { File f1 = new File("./hello.txt"); File f2 = new File("hello.txt");
import java.io.*;
public class FileEquals
{
public static void main(String[] args)
{
File f1 = new File("./hello.txt");
File f2 = new File("hello.txt");
System.out.println("f1: " + f1.getName());
System.out.println("f2: " + f2.getName());
System.out.println("f1.equals(f2) returns " + f1.equals(f2));
System.out.println("f1.compareTo(f2) returns " + f1.compareTo(f2));
}
}
以下是两种方法的实现:
/**
* Tests this abstract pathname for equality with the given object.
* Returns <code>true</code> if and only if the argument is not
* <code>null</code> and is an abstract pathname that denotes the same file
* or directory as this abstract pathname. Whether or not two abstract
* pathnames are equal depends upon the underlying system. On UNIX
* systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows
* systems it is not.
*
* @param obj The object to be compared with this abstract pathname
*
* @return <code>true</code> if and only if the objects are the same;
* <code>false</code> otherwise
*/
public boolean equals(Object obj) {
if ((obj != null) && (obj instanceof File)) {
return compareTo((File)obj) == 0;
}
return false;
}
如果您使用的是windows,请参见类
Win32FileSystem
比较方法如下所示,因此文件对象不同是很正常的
public int compare(File f1, File f2) {
return f1.getPath().compareToIgnoreCase(f2.getPath());
}
将这些行也添加到代码中
System.out.println(f1.getPath());
System.out.println(f2.getPath());
它会打印出来
.\hello.txt
hello.txt
因此,它们并不相等,因为使用文件对象的路径属性进行比较如果只想比较每个文件的内容,可以将内容读入如下字节数组:
byte[] f1 = Files.readAllBytes(file1);
byte[] f2 = Files.readAllBytes(file2);
FileInputStream f1 = new FileInputStream(file1);
DataInputStream d1 = new DataInputStream(f1);
FileInputStream f2 = new FileInputStream(file2);
DataInputStream d2 = new DataInputStream(f2);
byte b1 = d1.readByte();
byte b2 = d2.readByte();
然后比较你想要的
注意,这个方法调用只存在于Java7中。对于旧版本,Guava和Apache有类似的方法,但名称和细节不同
编辑:或者更好的选择(特别是在比较大文件时)可能是简单地逐字节比较,而不是将整个文件加载到内存中,如下所示:
byte[] f1 = Files.readAllBytes(file1);
byte[] f2 = Files.readAllBytes(file2);
FileInputStream f1 = new FileInputStream(file1);
DataInputStream d1 = new DataInputStream(f1);
FileInputStream f2 = new FileInputStream(file2);
DataInputStream d2 = new DataInputStream(f2);
byte b1 = d1.readByte();
byte b2 = d2.readByte();
然后从那里比较。不是,不是这样。因为equals是比较绝对路径的相等性(在上面的例子中,它类似于:
some-project\.\hello.txt
some-project\hello.txt
所以他们自然是不同的
public int compare(File f1, File f2) {
return f1.getPath().compareToIgnoreCase(f2.getPath());
}
似乎我必须写我自己的equals方法来支持它,
对吧?
可能是的。但首先,您必须知道要比较什么?仅比较路径名?如果是,请按以下方式比较其规范路径:
f1.getCanonicalPath().equals(f2.getCanonicalPath())
但是,如果您想要比较两个不同文件的内容,那么是,您应该编写自己的方法-或者只是从internet上的某个地方复制。要正确地测试equals,您必须调用getCanonicalFile()
将为等于返回true。请注意,getCanonicalFile可能会抛出IOException,因此我将其添加到方法签名中。我发现在两个文件上区分的更快方法如下 这只是解决问题的建议 不确定性能(如果每个文件都是10 GB怎么办?)
File File=new文件(“/tmp/File.txt”);
File secondFile=新文件(“/tmp/secondFile.txt”);
//字节差异
byte[]b1=Files.readAllBytes(file.toPath());
byte[]b2=Files.readAllBytes(secondFile.toPath());
布尔等于=数组。等于(b1,b2);
System.out.println(“相同?”+相等);
//列表差异
列表c1=Files.readAllLines(file.toPath());
List c2=Files.readAllLines(secondFile.toPath());
布尔containsAll=c1。containsAll(c2);
System.out.println(“相同?”+containsAll);
}
编辑
但是,unix系统上的diff实用程序会更快、更冗长。
取决于您需要比较的内容。如果您只想根据路径使用情况检查文件是否相同
java.nio.file.Files#isSameFile
例如
实际上我想做一些类似“fileList.contains(file)”的事情,这个方法调用equals方法。答案让我感到困惑。请参阅jdk中UnixFileSystem.java的源代码:public int compare(file f1,file f2){return f1.getPath().compareTo(f2.getPath());}@我不同意G.Demecki的观点:equals是比较绝对路径的相等+1个不错的帖子-今天我学到了一些东西(我还没有使用Java7,很高兴看到他们添加了一个文件实用程序)如果可以的话,我会先比较文件的大小。比较像that@unbeli请详细说明。我在很多单元测试中使用过类似的代码,其中一个文件包含正确的结果,另一个文件包含程序/算法生成的结果。OP不想这样做(正如他后来详细阐述的那样)但是Brian说了内容,他甚至把它大写。@user949300感谢我的帖子中添加的内容Java 7的Path类也是如此。但是也有类似Path.normalize()或Files.isSameFile()的方法通过显示实际输出,您可以在一段时间内保护这个问题的所有观众。我原以为
equals
和compareTo
的结果是矛盾的。事实并非如此,equals
返回false,而compareTo
返回-58,这在词典中表示“小于”.@Luciano:请注意,Files.isSameFile
在这种情况下会尝试打开文件,因为路径不相等,可能会因NoSuchFileException
而失败。
Assert.assertTrue(Files.isSameFile(
new File("some-project\.\hello.txt").toPath(),
new File("some-project\hello.txt").toPath()
));