Android File Compare compareContents(File file1, File file2)

Here you can find the source of compareContents(File file1, File file2)

Description

Compares the contents of the two supplied normal files, byte by byte.

License

Open Source License

Exception

Parameter Description
IllegalArgumentException if file1 or file2 is Check#validFile not valid;
SecurityException if a security manager exists and denies read access to either file
IOException if an I/O problem occurs

Declaration

public static long compareContents(File file1, File file2)
        throws IllegalArgumentException, SecurityException, IOException 

Method Source Code

/*/*from www  .j ava 2s  .c  om*/
Copyright ? 2008 Brent Boyer

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public License for more details.

You should have received a copy of the Lesser GNU General Public License along with this program (see the license directory in this project).  If not, see <http://www.gnu.org/licenses/>.
 */

import bb.science.FormatUtil;
import bb.util.Check;
import bb.util.StringUtil;
import bb.util.ThrowableUtil;
import bb.util.logging.LogUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.util.Random;
import java.util.logging.Level;
import org.junit.Assert;
import org.junit.Test;

public class Main{
    /**
     * Compares the contents of the two supplied normal files, byte by byte.
     * Returns the (zero-based) index of the first byte position where they differ, else returns -1 if they are identical.
     * If one file is smaller than the other, but the bytes in the 2 files are identical up to where the smaller ends,
     * then the value returned is the length of the smaller file (i.e. the index of the first extra byte in the larger file).
     * <p>
     * Contract: the result is -1 if and only the files are identical, else is >= 0.
     * <p>
     * @throws IllegalArgumentException if file1 or file2 is {@link Check#validFile not valid};
     * @throws SecurityException if a security manager exists and denies read access to either file
     * @throws IOException if an I/O problem occurs
     */
    public static long compareContents(File file1, File file2)
            throws IllegalArgumentException, SecurityException, IOException {
        Check.arg().validFile(file1);
        Check.arg().validFile(file2);

        InputStream in1 = null;
        InputStream in2 = null;
        try {
            in1 = new FileInputStream(file1);
            in2 = new FileInputStream(file2);

            int bufferSize = calcBufferSize(file1, file2);
            byte[] bytes1 = new byte[bufferSize];
            byte[] bytes2 = new byte[bufferSize];

            long index = 0;
            while (true) {
                // attempt a fast bulk read into byte arrays:
                int nRead1 = in1.read(bytes1);
                int nRead2 = in2.read(bytes2);

                // see if any ran out of data:
                int minRead = Math.min(nRead1, nRead2);
                if (minRead == -1) { // at least one ran out of data
                    if (nRead1 == nRead2)
                        return -1; // both ran out of data, and so the files are identical
                    else
                        return index; // only 1 ran out of data, and so the files are NOT identical
                }

                // compare those parts of the byte[] which are both populated with data:
                int offset = findWhereDiffer(bytes1, bytes2, minRead);
                if (offset > -1)
                    return index + offset; // a difference was found, return the index where first one occurs
                else
                    index += minRead; // no differences found so far, so increment index and continue search

                // NASTY CORNER CASE: one of the bulk reads failed to pull in as much data as the other; resolve by doing a slow byte by byte read and compare:
                if (nRead1 != nRead2) {
                    LogUtil.getLogger2()
                            .logp(Level.WARNING,
                                    "FileUtil",
                                    "compareContents",
                                    "nRead1 = "
                                            + nRead1
                                            + " != nRead2 = "
                                            + nRead2
                                            + "; while need to resolve by doing a slow byte by byte read and compare");
                    for (; nRead1 < nRead2; nRead1++) {
                        int read1 = in1.read();
                        if ((read1 == -1) || (read1 != bytes2[nRead1]))
                            return index;
                        else
                            ++index;
                    }
                    for (; nRead2 < nRead1; nRead2++) {
                        int read2 = in2.read();
                        if ((read2 == -1) || (read2 != bytes1[nRead2]))
                            return index;
                        else
                            ++index;
                    }
                }
            }
        } finally {
            StreamUtil.close(in1);
            StreamUtil.close(in2);
        }
    }
    private static int calcBufferSize(File file1, File file2) {
        int lowerBound = 16;
        int upperBound = 1024 * 1024;
        long minLength = Math.min(file1.length(), file2.length());
        if (minLength < lowerBound)
            return lowerBound;
        else if (minLength > upperBound)
            return upperBound;
        else
            return (int) minLength;
    }
    private static int findWhereDiffer(byte[] bytes1, byte[] bytes2,
            int limit) {
        for (int i = 0; i < limit; i++) {
            if (bytes1[i] != bytes2[i])
                return i;
        }
        return -1;
    }
}

Related

  1. diff(File f1, File f2)