1

我有一个 Java 工具,可以生成 100,000 多个文件,我随后在流程的“步骤 2”中使用这些文件。由于“第 2 步”的性质,我不想要任何大于 1MB 的文件。这是我用来删除这些文件的代码:

File[] files = root.listFiles();
for (File file : files) {
    if (file.isFile()) {
        if (file.length > 1048576) { //size of MB
            //delete the file
            file.delete();
        }
    }
}

当文件数量相对较少时,这可以正常工作。但是,当 n > 100,000 时,由于内存限制,调用 listFiles() 会使我的系统崩溃。我知道您可以根据文件类型过滤结果,但是有没有办法根据文件大小来过滤结果?或者,是否有另一种方法可以轻松地根据文件大小进行大批量删除,而不会使我的系统崩溃?

FWIW,我正在运行 RedHat 6。

4

4 回答 4

5

我认为您应该查看DirectoryStream。正如您所期望的,它允许您以流方式迭代目录内容,因此您不会从大目录中耗尽内存:

try (DirectoryStream<Path> stream = Files.newDirectoryStream(dirPath)) {
   for (Path entry : stream) {
       File file = entry.toFile();
       if (file.isFile()) {
          if (file.length > 1048576) { //size of MB
             //delete the file
             file.delete();
          }
       }
   }
}

您可能想查看Files#listFiles(FileFilter). 至少在我的版本(Java 1.7,Mac OS)上,它是通过调用Files#list()然后复制所有匹配来实现的,这意味着它Files#list().

于 2013-03-22T20:10:07.500 回答
3

您最好的选择是使用listFiles()接收 a的版本FileFilter,注意在accept()方法中您可以在返回 之前询问每个文件的大小File[],并且只包含具有预期大小的文件。这样做的好处是只返回需要删除的文件。

于 2013-03-22T20:01:43.797 回答
0

您可以尝试在 File.listFiles 中使用 FileFilter,它只会返回您需要删除的文件。

于 2013-03-22T20:02:21.377 回答
0

使用 Apache Commons FileUtils。您可能会发现有用的方法是FileUtils#iterateFiles(File directory,IOFileFilter fileFilter,IOFileFilter dirFilter)( javadoc )。您可以使用IOFileFilterjavadoc),它允许您指定在迭代时要接受的文件的大小。

难道这是listFiles()在幕后呼唤?绝对地。但是你不知道,直到你尝试:)

于 2013-03-22T20:09:02.640 回答