A9c8a6d8eed437bb33d504cae365bf57

This method checks if the contents of two text files are equal. Is this the best way?
How could it work also for binary files?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
	public static boolean fileContentsEquals(File file1, File file2) {
		InputStream is1 = null;
		InputStream is2 = null;
		if (file1.length() != file2.length())
			return false;

		try {
			is1 = new FileInputStream(file1);
			is2 = new FileInputStream(file2);

			return inputStreamEquals(is1, is2);

		} catch (Exception ei) {
			return false;
		} finally {
			try {
				if (is1 != null)
					is1.close();
				if (is2 != null)
					is2.close();
			} catch (Exception ei2) {
			}
		}
	}

	public static boolean inputStreamEquals(InputStream is1, InputStream is2) {
		if (is1 == is2)
			return true;
		if (is1 == null && is2 == null)
			return true;
		if (is1 == null || is2 == null)
			return false;
		try {
			int read1 = -1;
			int read2 = -1;

			do {
				int offset1 = 0;
				while (offset1 < BUFFSIZE && (read1 = is1.read(buff1, offset1, BUFFSIZE - offset1)) >= 0) {
					offset1 += read1;
				}

				int offset2 = 0;
				while (offset2 < BUFFSIZE && (read2 = is2.read(buff2, offset2, BUFFSIZE - offset2)) >= 0) {
					offset2 += read2;
				}
				if (offset1 != offset2)
					return false;
				if (offset1 != BUFFSIZE) {
					Arrays.fill(buff1, offset1, BUFFSIZE, (byte) 0);
					Arrays.fill(buff2, offset2, BUFFSIZE, (byte) 0);
				}
				if (!Arrays.equals(buff1, buff2))
					return false;
			} while (read1 >= 0 && read2 >= 0);
			if (read1 < 0 && read2 < 0)
				return true; // both at EOF
			return false;

		} catch (Exception ei) {
			return false;
		}
	}

Refactorings

No refactoring yet !

1e8f141e7857d397d8020ed3b759e88a

Maciej Piechotka

August 18, 2008, August 18, 2008 10:40, permalink

No rating. Login to rate!

1. Yes. It will work on bytes
2. May be something like that - 3 lines in NIO.

1
2
3
4
5
public static boolean fileContentsEquals(File file1, File file2) throws IOException {
  ByteBuffer buf1 = new FileInputStream(file1).getChannel().map(MapMode.READ_ONLY, 0, file1.length());
  ByteBuffer buf2 = new FileInputStream(file2).getChannel().map(MapMode.READ_ONLY, 0, file2.length());
  return buf1.equals(buf2);
}
Avatar

TFrey

August 18, 2008, August 18, 2008 15:10, permalink

No rating. Login to rate!

I think this solution is basically the same idea as yours but uses stuff from the Java NIO libraries. In production code you'll have to make sure you close everything and handle exceptions properly but that really clutters the code so I'll leave it as an exercise for the reader ;-) It seems to work for any kind of file because it's comparing raw bytes instead of characters.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private static boolean areSame(File f1, File f2) throws IOException
{
        FileChannel fc1 = new FileInputStream(f1).getChannel();
        FileChannel fc2 = new FileInputStream(f2).getChannel();

	if(fc1.size() != fc2.size())
		return false;
		
	ByteBuffer buf1 = ByteBuffer.allocate(1024);
	ByteBuffer buf2 = ByteBuffer.allocate(1024);

	while(fc1.read(buf1) != -1 && fc2.read(buf2) != -1)
	{
		if(buf1.compareTo(buf2) != 0)
			return false;

		buf1.clear(); buf2.clear();
	}

	return true;
}
1e8f141e7857d397d8020ed3b759e88a

Maciej Piechotka

August 19, 2008, August 19, 2008 08:14, permalink

No rating. Login to rate!

I'm tring once more - I've posted 3 minutes after the orginal post but it get spammed:

1
2
3
4
5
6
7
8
9
10
11
private static boolean areSame(File f1, File f2) throws IOException
{
  if(f1 == f2)
    return true;
  if(f1 == null || f2 == null)
    return false;

  MappedByteBuffer buf1 = new FileInputStream(f1).getChannel().map(FileChannel.MapMode.READ_ONLY, 0, f1.length);
  MappedByteBuffer buf2 = new FileInputStream(f2).getChannel().map(FileChannel.MapMode.READ_ONLY, 0, f1.length);
  return buf1.equals(buf2);
}

Your refactoring





Format Copy from initial code

or Cancel