Description
When you are learning Java, network programming can be a great source of practicing Java. In this program, we will see how we can compare two different files in Java. Comparing files in java also can help you to differentiate between the local and the remote files. You can quickly identify the duplicate lines, which allows you to remove the file entirely. First, we will be comparing the files using BufferedReader but this way of comparing files is not memory efficient and requires more execution time. Hence, we will be using a highly advanced technique called memory mapping using RandomAccessFile from java.io package.
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class CompareTextFiles { public static void main(String[] args) throws IOException { BufferedReader reader1 = new BufferedReader(new FileReader("C:\\file1.txt")); BufferedReader reader2 = new BufferedReader(new FileReader("C:\\file2.txt")); String line1 = reader1.readLine(); String line2 = reader2.readLine(); boolean areEqual = true; int lineNum = 1; while (line1 != null || line2 != null) { if(line1 == null || line2 == null) { areEqual = false; break; } else if(! line1.equalsIgnoreCase(line2)) { areEqual = false; break; } line1 = reader1.readLine(); line2 = reader2.readLine(); lineNum++; } if(areEqual) { System.out.println("Two files have same content."); } else { System.out.println("Two files have different content. They differ at line "+lineNum); System.out.println("File1 has "+line1+" and File2 has "+line2+" at line "+lineNum); } reader1.close(); reader2.close(); } }
This program is simple in nature and may take up a lot of memory and time to execute. For a very fast and efficient solution, you need to use a highly advanced technique called memory-mapping. Files that are mapped by the memory are read directly by your operating system. The OS allocates the memory itself and hence the program doesn't consume heap memory.
Open your files by using the RandomAccessFile class and ask for the channel from this object if you want to memory map the two files. MappedByteBuffer, a representation of the memory area of your file's contents can be created from the channel that you get access from the RandomAccessFile class.
The below program outlines what you need to do.
package packt.java9.network.niodemo; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class MapCompare { public static void main(String[] args) throws IOException { long start = System.nanoTime(); FileChannel ch1 = new RandomAccessFile("sample.txt", "r").getChannel(); FileChannel ch2 = new RandomAccessFile("sample-copy.txt", "r").getChannel(); if (ch1.size() != ch2.size()) { System.out.println("Files have different length"); Return; } long size = ch1.size(); ByteBuffer m1 = ch1.map(FileChannel.MapMode.READ_ONLY, 0L, size); ByteBuffer m2 = ch2.map(FileChannel.MapMode.READ_ONLY, 0L, size); for (int pos = 0; pos < size; pos++) { if (m1.get(pos) != m2.get(pos)) { System.out.println("Files differ at position " + pos); return; } } System.out.println("Files are identical, you can delete one of them."); long end = System.nanoTime(); System.out.print("Execution time: " + (end - start) / 1000000 + "ms"); } }