【问题标题】:How to compare two java.io.File Programmatically如何以编程方式比较两个 java.io.File
【发布时间】:2016-07-22 13:06:36
【问题描述】:

有没有办法在 Android 中比较两个文件?

例如:我在同一个文件夹下有两个文件,它们是相同的。 它们相同(大小也一样),但它们的名字就像 myFileA.pdfmyFileB.pdf。那么我怎样才能确定它们是 是否相同。

我已经尝试过的:

  • compareTo() 方法:尝试过myFileA.compare(myFileB),但它给出了一些奇怪的值,例如 -1、-2 等。我认为这些值取决于文件的 PATH
  • myFile.length():但是在一些极少数情况下(非常罕见的情况),两个不同的文件可以具有相同的大小,所以我认为这不是正确的方法。

注意:我告诉过文件在 same 文件夹下,例如,它们可以在任何地方,例如 myFileA.pdf 可以在 NewFolder1myFileB.pdf 可以在 NewFolder2 中。

【问题讨论】:

  • 也许计算两者的哈希值并比较它们?
  • "尝试了 myFileA.compare(myFileB),但它给出了一些奇怪的值,例如 -1、-2 等。"你检查过compare()的JavaDocs吗?
  • stackoverflow.com/questions/27379059/… stackoverflow.com/questions/21764299/… codereview.stackexchange.com/questions/90147/… 和许多其他资源可以使用 Google 搜索 compare two file contents in java 找到。
  • 当两个文件很大并且从第一个字节开始内容不同时,计算哈希是一个不错的选择,但可能不是最佳选择。
  • @Meet “做到了,但它们给出了不同的值”您确定要比较重复文件而不是“相似”文件吗?

标签: java android


【解决方案1】:

前段时间,我编写了一个实用程序来以一种有效的方式比较两个流的内容:找到第一个差异时停止比较。 这是我认为很容易解释的代码:

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;

public class FileComparator implements Comparator<File> {

    @Override
    public int compare(File file1, File file2) {

        // one or both null
        if (file1 == file2) {
            return 0;
        } else if (file1 == null && file2 != null) {
            return -1;
        } else if (file1 != null && file2 == null) {
            return 1;
        }

        if (file1.isDirectory() || file2.isDirectory()) {
            throw new IllegalArgumentException("Unable to compare directory content");
        }

        // not same size
        if (file1.length() < file2.length()) {
            return -1;
        } else if (file1.length() > file2.length()) {
            return 1;
        }

        try {
            return compareContent(file1, file2);
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        }

    }

    private int bufferSize(long fileLength) {
        int multiple = (int) (fileLength / 1024);
        if (multiple <= 1) {
            return 1024;
        } else if (multiple <= 8) {
            return 1024 * 2;
        } else if (multiple <= 16) {
            return 1024 * 4;
        } else if (multiple <= 32) {
            return 1024 * 8;
        } else if (multiple <= 64) {
            return 1024 * 16;
        } else {
            return 1024 * 64;
        }
    }

    private int compareContent(File file1, File file2) throws IOException {

        final int BUFFER_SIZE = bufferSize(file1.length());

        // check content
        try (BufferedInputStream is1 = new BufferedInputStream(new FileInputStream(file1), BUFFER_SIZE); BufferedInputStream is2 = new BufferedInputStream(new FileInputStream(file2), BUFFER_SIZE);) {

            byte[] b1 = new byte[BUFFER_SIZE];
            byte[] b2 = new byte[BUFFER_SIZE];

            int read1 = -1;
            int read2 = -1;
            int read = -1;

            do {
                read1 = is1.read(b1);
                read2 = is2.read(b2);

                if (read1 < read2) {
                    return -1;
                } else if (read1 > read2) {
                    return 1;
                } else {
                    // read1 is equals to read2
                    read = read1;
                }

                if (read >= 0) {
                    if (read != BUFFER_SIZE) {
                        // clear the buffer not filled from the read
                        Arrays.fill(b1, read, BUFFER_SIZE, (byte) 0);
                        Arrays.fill(b2, read, BUFFER_SIZE, (byte) 0);
                    }
                    // compare the content of the two buffers
                    if (!Arrays.equals(b1, b2)) {
                        return new String(b1).compareTo(new String(b2));
                    }
                }
            } while (read >= 0);

            // no difference found
            return 0;
        }
    }
}

【讨论】:

    【解决方案2】:

    比较两个文件:

    public static boolean compareFiles(File file1, File file2) {
            byte[] buffer1 = new byte[1024];
            byte[] buffer2 = new byte[1024];
            try {
                FileInputStream fileInputStream1 = new FileInputStream(file1);
                FileInputStream fileInputStream2 = new FileInputStream(file2);
                while (fileInputStream1.read(buffer1) != -1) {
                    if (fileInputStream2.read(buffer2) != -1 && !Arrays.equals(buffer1, buffer2))
                        return false;
                }
                return true;
            } catch (Exception ignore) {
                return false;
            }
        }
    

    当然,在您这样做之前,您必须比较文件大小。只有匹配了,才比较内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-07
      • 2017-07-23
      • 2014-09-11
      • 2011-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多