12

当我使用 Java 列出具有 300,000 个文件的目录的文件时,会发生内存不足。

String[] fileNames = file.list();

我想要的是一种可以增量列出目录的所有文件的方法,无论该特定目录中有多少文件,并且默认的 64M 堆限制不会出现“内存不足”问题。

我有一段时间谷歌了,在纯 Java 中找不到这样的方法。
请帮我!!

注意,JNI 是一种可能的解决方案,但我讨厌 JNI。

4

5 回答 5

5

我知道您说“使用默认的 64M 堆限制”,但让我们看看事实 - 您希望使用 Java 提供给您的机制在内存中保存(可能)大量项目。所以,除非有一些你不能的可怕原因,否则我会说增加堆是要走的路。

这是 JavaRanch 上相同讨论的链接:http: //www.coderanch.com/t/381939/Java-General/java/iterate-over-files-directory

编辑,回应评论:我说他想在内存中保存大量项目的原因是因为这是 Java 提供的唯一机制,用于在不使用本机接口或平台特定机制的情况下列出目录(并且 OP 说他想要“纯Java”)。

于 2010-01-13T04:14:03.923 回答
5

对您来说唯一可能的解决方案是 Java7,然后您应该使用迭代器。

final Path p = FileSystems.getDefault().getPath("Yourpath");
Files.walk(p).forEach(filePath -> {
        if (Files.isRegularFile(filePath)) {
            //Do something with filePath
        }
});
于 2012-07-23T07:00:26.370 回答
2

你在这里有点不走运。至少需要创建 300k 个字符串。平均长度为 8-10 个字符,每个字符 2 个字节,最小为 6Mb。为每个字符串(8 个字节)添加对象指针开销,就会遇到内存限制。

如果您绝对必须在一个目录中拥有这么多文件,我不建议这样做,因为您的文件系统会出现问题,那么最好的办法是通过 Runtime.exec 运行本机进程(而不是 JNI)。请记住,您会将自己束缚在操作系统上(ls vs dir)。您将能够以一个大字符串的形式获取文件列表,并负责将其后处理为您想要的内容。

希望这可以帮助。

于 2010-01-13T04:19:46.153 回答
1

在目录中拥有 300 000 个文件并不是一个好主意 - AFAIK 文件系统不擅长在单个节点中拥有那么多子节点。不过,有趣的问题。

编辑:以下没有帮助,请参阅评论。

我认为您可以使用 FileFilter,拒绝所有文件,然后在过滤器中处理它们。

        new File("c:/").listFiles( new FileFilter() {
            @Override   public boolean accept(File pathname) {
                processFile();
                return false;
            }
        });
于 2010-01-13T04:16:10.347 回答
0

如果您可以使用 Java 7 或更高版本编写代码,那么以下是一个不错的选择。

Files.newDirectoryStream(路径目录)

是 API 的 java 文档。

希望这可以帮助。

于 2016-07-01T08:37:27.193 回答