当前位置: 首页 > 知识库问答 >
问题:

如何递归地在目录中查找重复文件(二进制或文本)(基于内容而不是文件名或长度)

潘安平
2023-03-14

我有一个包含子目录的目录,其中包含文本或二进制文件(如图片)。我需要找到重复的文件,可以在不同的子目录和不同的名称。所以,我需要使用一些算法来查看文件内部,而不依赖于文件名或文件长度。

共有2个答案

臧烨烁
2023-03-14

如果没有mapFilesSize,您的方法iterateOverDirectory可以变成:

private static void iterateOverDirectory(File rootDir) throws Exception {
    for (File file : rootDir.listFiles()) {
        if (file.isDirectory()) {
            iterateOverDirectory(file);
        }
        else {
            mapFilesHash.computeIfAbsent(checksum(file), k -> new ArrayList<>()).add(file);
        }
    }
}
闾丘玮
2023-03-14

我可以想出一个快速的解决办法。我知道这段代码可以写得更好,但从功能上看,它的工作非常完美。我甚至在jpeg和gif文件上进行了测试。

public static Map<String, List<File>> mapFilesHash = new HashMap<String, List<File>>();

public static MessageDigest md ;
static {
    try {
    md = MessageDigest.getInstance("MD5");
    } catch (Exception ex) {}
}

private static String checksum(File file) throws IOException {
    FileInputStream fis = new FileInputStream(file);
    byte[] byteArray = new byte[1024];
    int bytesCount = 0;
    while ((bytesCount = fis.read(byteArray)) != -1) {
        md.update(byteArray, 0, bytesCount);
    }
    fis.close();
    byte[] bytes = md.digest();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < bytes.length; i++) {
        sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
    }
    return sb.toString();
}


public static void findDuplicateFiles(File rootDir) throws Exception {
    iterateOverDirectory(rootDir);
    System.out.println("based on hash "+mapFilesHash.size());
    for (List<File> files: mapFilesHash.values()) {
        if (files.size() > 1 ) {
            System.out.println(files);
        }
    }
    
}

private static void iterateOverDirectory (File rootDir) throws Exception {
    for (File file : rootDir.listFiles()) {
        if (file.isDirectory()) {
            iterateOverDirectory(file);
        } else {
            if (mapFilesSize.get(file.length()) == null) {
                mapFilesSize.put(file.length(), new ArrayList<>());
            }
            mapFilesSize.get(file.length()).add(file);

            String md5hash = checksum(file);
            if (mapFilesHash.get(md5hash) == null) {
                mapFilesHash.put(md5hash, new ArrayList<>());
            }
            mapFilesHash.get(md5hash).add(file);
        }
    }
}
 类似资料:
  • 问题内容: Python似乎具有复制文件的功能(例如)和复制目录的功能(例如),但是我还没有找到能够同时处理两者的函数。当然,检查要复制文件还是目录很简单,但这似乎很奇怪。 确实没有像unix命令那样工作的标准函数,即同时支持目录和文件以及递归复制吗?在Python中解决此问题的最优雅方法是什么? 问题答案: 建议您先致电,如果引发异常,请重试。

  • 我有一个文件夹,其中包含子文件夹和一些其他文件。 这些文件的命名方式如下 我试图在上面的模式中找到只与“xxxxxx”匹配的重复文件,忽略其余的。分机。dat没有改变。但是abc和DEF的长度可能会改变。按周期划分的顺序也不会改变。 我猜我需要用下面的方式使用Find 我需要帮助想出正则表达式。谢谢 例如:对于名为“epg”的文件。ktt。crwqdd。dat,我需要找到包含“crwqdd”的重复

  • 问题内容: 我正在尝试获取目录中所有文本文件的名称。如果目录中包含子目录,那么我也想在这些子目录中获取任何文本文件。我不确定如何继续执行任意数量的子目录。 现在,下面的代码仅获取当前目录中的所有文本文件以及该目录中的子目录。对于找到的每个子目录,它还会找到任何文本文件和更深的子目录。问题是,如果那些更深的子目录还有更深的子目录,那么我找不到所有的文本文件。这似乎是一个需要递归的问题,因为我不知道它

  • grep用于在文件内搜索,查看是否有任何行与给定的正则表达式匹配。然而,我有这种情况--我想编写一个将与文件名本身(而不是文件内容)匹配的正则表达式。我将从系统的根目录运行它,以找到所有与正则表达式匹配的文件。

  • 问题内容: 我正在编写一个Python备份脚本,需要在目录(及其子目录)中找到最旧的文件。我还需要仅将其过滤为* .avi文件。 该脚本将始终在Linux计算机上运行。有什么方法可以在Python中完成,还是运行一些Shell命令会更好? 目前,我正在努力获取特定分区上的可用空间,如果可用空间不足5 GB,我想开始删除最旧的文件,直到满足该条件为止。 问题答案: 嗯 Nadia的答案是接近你什么

  • 问题内容: 我想检查我的Go代码中文件的存在,但是我找不到一种好的方法。 我知道有一种Java中的File方法:如果文件或目录存在,则返回true。 但是如何在Go中完成呢? 问题答案: 编辑以添加错误处理。