简体   繁体   English

验证文件是用Java复制的

[英]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. 在我进行验证之前,我正在关闭两个FileStream,但由于尺寸不同,它仍然会失败。 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. 在此之前的其余代码是使用Util来复制流,并且它们都工作正常,所以我只需要一个更好的验证方法。

One wonderful way you can check is to compare md5 hashes. 您可以检查的一个很棒的方法是比较md5哈希值。 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. 虽然md5哈希并不意味着它们也是相同的,但它比检查长度更好,尽管更长的过程。

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: 你可以使用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! 确保不要忽略close方法抛出的异常!

Update: If you use FileOutputStream , you can also make sure everything was written properly by calling fileOutputStream.getFD().sync() before closing your fileOutputStream . 更新:如果您使用FileOutputStream ,您还可以通过在关闭fileOutputStream之前调用fileOutputStream.getFD().sync()来确保所有内容fileOutputStream.getFD().sync()正确写入。

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? 你真的看过这两个文件看看有什么不同吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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