Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java file equals

I don't know about you guys but at least I expected that f1 would be equal to f2 in the below code but apparently that's not the case! What's your thoughts about this? It seems like I have to write my own equals method to support it, right?

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));
    }
}
like image 251
aandeers Avatar asked Jan 19 '12 17:01

aandeers


People also ask

Is .equals the same as == Java?

equals() method for content comparison. In simple words, == checks if both objects point to the same memory location whereas . equals() evaluates to the comparison of values in the objects.

What does .equals mean in Java?

The equals() method compares two strings, and returns true if the strings are equal, and false if not.

What is the use of == in Java?

What is == in Java? == is an operator that compares the memory or reference location of an object in the heap.


3 Answers

Not, it's not the case. Because equals is comparing equality of absolute paths (in your case above it is something like:

some-project\.\hello.txt
some-project\hello.txt

So they are naturally different.

It seems like I have to write my own equals method to support it, right?

Probably yes. But first of all, you have to know what you want to compare? Only pathnames? If yes, compare its canonical path in this way:

f1.getCanonicalPath().equals(f2.getCanonicalPath())

But if you want compare content of two different files, then yes, you should write your own method - or simply just copy from somewhere on the internet.

like image 57
G. Demecki Avatar answered Oct 12 '22 05:10

G. Demecki


To properly test equals, you must call getCanonicalFile(). e.g.

public static void main(String[] args) throws IOException
   {
       File f1 = new File("./hello.txt").getCanonicalFile();
       File f2 = new File("hello.txt").getCanonicalFile();
       System.out.println("f1: " + f1.getAbsolutePath());
       System.out.println("f2: " + f2.getAbsolutePath());
       System.out.println("f1.equals(f2) returns " + f1.equals(f2));
       System.out.println("f1.compareTo(f2) returns " + f1.compareTo(f2));
   }

Will return true for equals. Note that getCanonicalFile may throw an IOException so I added that to the method signature.

like image 29
user949300 Avatar answered Oct 12 '22 05:10

user949300


If you only want to compare the CONTENTS of each file, you could read the contents into a byte array like this:

byte[] f1 = Files.readAllBytes(file1);
byte[] f2 = Files.readAllBytes(file2);

And then compare exactly what you want from there.

Note that this method call only exists in Java 7. For older versions, Guava and Apache have methods to do similar but with different names and details.

Edit: OR a better option (especially if you're comparing large files) might be to simply compare byte by byte rather than loading the entire file into memory, like this:

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();

And then compare from there.

like image 5
Brian Snow Avatar answered Oct 12 '22 05:10

Brian Snow