如何在Java中快速检索目录列表?
假设有一个非常简单的程序,它列出了给定目录的所有子目录。听起来很简单?除了在Java中列出所有子目录的唯一方法是将文件名过滤器与File.list()结合使用。
这适用于微不足道的情况,但是当文件夹有150,000个文件和2个子文件夹时,在那里等待45秒来迭代所有文件并测试file.isDirectory()是愚蠢的。有没有更好的方法来列出子目录?
对不起,请保存有关在同一目录中有太多文件的讲座。我们的实时环境将此作为要求的一部分。
假设有一个非常简单的程序,它列出了给定目录的所有子目录。听起来很简单?除了在Java中列出所有子目录的唯一方法是将文件名过滤器与File.list()结合使用。
这适用于微不足道的情况,但是当文件夹有150,000个文件和2个子文件夹时,在那里等待45秒来迭代所有文件并测试file.isDirectory()是愚蠢的。有没有更好的方法来列出子目录?
对不起,请保存有关在同一目录中有太多文件的讲座。我们的实时环境将此作为要求的一部分。
如前所述,这基本上是一个硬件问题。磁盘访问总是很慢,大多数文件系统并不是真正设计用于处理包含那么多文件的目录。
如果由于某种原因必须将所有文件存储在同一目录中,我认为您必须维护自己的缓存。这可以使用本地数据库(如sqlite,HeidiSQL或HSQL)来完成。如果你想要极致的性能,请使用 java TreeSet 并将其缓存在内存中。这意味着至少您必须减少读取目录的频率,并且可能会在后台完成。通过使用系统本机文件更新通知 API(linux 上的 inotify)订阅对目录的更改,可以进一步减少刷新列表的需要。
这对你来说似乎是不可能的,但我曾经通过将文件“散列”到子目录中解决了类似的问题。就我而言,挑战在于使用数字ID存储数百万张图像。我构造了如下目录结构:
images/[id - (id % 1000000)]/[id - (id % 1000)]/[id].jpg
这对我们来说效果很好,这是我推荐的解决方案。您可以执行类似于字母数字文件名的操作,只需取文件名的前两个字母,然后取下两个字母。我也做过一次,它也做了这项工作。
您知道可能的子目录名称的有限列表吗?如果是这样,请在所有可能的名称上使用循环并检查目录是否存在。
否则,您无法在大多数底层操作系统中仅获取目录名称(例如,在Unix中,目录列表仅读取“目录”文件的内容,因此无法在不列出所有文件的情况下快速找到“仅目录”)。
但是,在Java7的NIO.2中(参见 http://java.sun.com/developer/technicalArticles/javase/nio/#3),有一种方法可以获得一个流目录列表,这样您就不会得到一个完整的文件元素数组来混乱您的内存/网络。