当列表文件在目录中时OutOfMemory

时间:2010-01-13 04:08:56

标签: java file out-of-memory

当我列出包含300,000个带Java文件的目录的文件时,会发生内存不足。

String[] fileNames = file.list();

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

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

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

5 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分:4)

唯一可行的解​​决方案是Java 7,然后您将使用迭代器。

final Path p = FileSystems.getDefault().getPath("Yourpath");
Files.walk(p).forEach(filePath -> {
        if (Files.isRegularFile(filePath)) {
            //Do something with filePath
        }
});

答案 2 :(得分:2)

你在运气方面有点不走运。至少需要创建300k字符串。平均长度为8-10个字符,每个字符2个字节,最小为6Mb。每个字符串添加对象指针开销(8个字节),然后进入内存限制。

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

希望这有帮助。

答案 3 :(得分:1)

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

编辑:以下内容无法提供帮助,请参阅评论。

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

        new File("c:/").listFiles( new FileFilter() {
            @Override   public boolean accept(File pathname) {
                processFile();
                return false;
            }
        });

答案 4 :(得分:0)

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

Files.newDirectoryStream(Path dir)

Here是API的java文档。

希望这有帮助。