简体   繁体   中英

Verify file is copied in Java

I'm working on moving some files to a different directory in my project and it's working great, except for the fact that I can't verify it's moved properly.

I want to verify the length of the copy is the same as the original and then I want to delete the original. I'm closing both FileStreams before I do my verification but it still fails because the sizes are different. Below is my code for closing the streams, verification and deletion.

 in.close();
 out.close();

 if (encCopyFile.exists() && encCopyFile.length() == encryptedFile.length())
     encryptedFile.delete();

The rest of the code before this is using a Util to copy the streams, and it's all working fine so really I just need a better verification method.

One wonderful way you can check is to compare md5 hashes. Checking file length doesn't mean they are the same. While md5 hashes doesn't mean they are the same either, it is better than checking the length albeit a longer process.

public class Main {

    public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
        System.out.println("Are identical: " + isIdentical("c:\\myfile.txt", "c:\\myfile2.txt"));
    }

    public static boolean isIdentical(String leftFile, String rightFile) throws IOException, NoSuchAlgorithmException {
        return md5(leftFile).equals(md5(rightFile));
    }

    private static String md5(String file) throws IOException, NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("MD5");
        File f = new File(file);
        InputStream is = new FileInputStream(f);
        byte[] buffer = new byte[8192];
        int read = 0;
        try {
            while ((read = is.read(buffer)) > 0) {
                digest.update(buffer, 0, read);
            }
            byte[] md5sum = digest.digest();
            BigInteger bigInt = new BigInteger(1, md5sum);
            String output = bigInt.toString(16);
            return output;
        } finally {
            is.close();
        }
    }
}

You could use commons io:

org.apache.commons.io.FileUtils.contentEquals(File file1, File file2) 

or you could use checksum methods:

org.apache.commons.io.FileUtils:
static Checksum checksum(File file, Checksum checksum) //Computes the checksum of a file using the specified checksum object.
static long checksumCRC32(File file) //Computes the checksum of a file using the CRC32 checksum routine.

If you get no exception while copying streams, you should be OK. Make sure you don't ignore exceptions thrown by close method!

Update: If you use FileOutputStream , you can also make sure everything was written properly by calling fileOutputStream.getFD().sync() before closing your fileOutputStream .

Of course, if you want to absolutely make sure that files are the same, you can compare their checksums/digests, but that sounds bit paranoid to me.

You could include a checksum in your copy operation. Perform a checksum on the destination file and see that it matches a checksum on the source.

If the sizes are different, perhaps you are not flushing the output stream before closing it.

Which file is bigger? What are the sizes of each file? Have you actually looked at the two files to see what is different?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM