列出目录中所有文件(包括子目录)的最有效方法是什么?

时间:2010-03-19 18:56:06

标签: java file servlets recursion

我正在编写一个servlet,它将检查服务器上的目录(Web容器外部),并递归搜索某些文件(通过某些文件,我指的是具有特定扩展名的文件以及某个命名惯例)。找到这些文件后,servlet会响应所有找到的文件的长列表(包括文件的完整路径)。我的问题是,有太多的文件和目录,我的servlet变得非常慢。我想知道这类问题是否有最佳实践或现有的servlet?简单地编译整个文件列表并通过客户端的js / jquery进行过滤会更有效吗?

4 个答案:

答案 0 :(得分:2)

磁盘访问速度很慢,随着文件和目录数量的增加,当您通过目录树使用传统的递归搜索时,您将很快达到servlet无用的程度。如果您有大量并发用户同时执行相同的搜索,您将特别快速达到此限制。

相反,使用外部批处理作业生成文件列表要好得多,然后可以通过数据库调用将其读入servlet,甚至只需解析包含由换行符分隔的所有文件名的文件。在Linux上使用“find”是一种简单的方法:

find <path_to_directory> -name '*.bin' > list_files.txt

这将列出在特定目录中以.bin结尾的每个文件名,并将其输出到名为list_files.txt的文件中。然后,您的servlet可以读取该文件并从那里创建文件列表。

答案 1 :(得分:1)

如果你真的有大量文件,你可能会考虑产生一个外部进程来进行搜索。如果你在类似unix的服务器(如linux)上运行,你可以通过让“find”命令搜索你并解析它的输出来获得速度提升。

您可以谷歌搜索有关如何使用“查找”的许多示例。

答案 2 :(得分:1)

我看到为什么这个过程可能会缓慢进行的两个可能原因:

1)磁盘I / O耗时太长。这将是一个你无法做多少的真正约束。通常,操作系统非常擅长将结构保留在内存中,以便更快地查找文件夹中的文件。如果它太慢了,你可能必须自己在内存中构建一个索引。这一切都取决于你是如何做到的。

在任何情况下,如果这是问题(您可以尝试测量),那么过滤客户端无法提供帮助,因为无论您在何处执行,都不应该花费很长时间。相反,您将通过向其发送更多数据来使客户端变慢。

2)您的目录遍历有问题。你说它是“递归的”。如果你的意思是它实际上是递归的,即每当遇到一个新目录时调用自身的方法,那么这可能会减慢你的速度(开销确实加起来)。在维基百科上有一些关于tree traversal的东西,但基本上只是使用队列或堆栈来跟踪你在遍历中的位置,而不是使用你的方法状态来执行此操作。

请注意,文件系统实际上不是树,但我假设它是在这种情况下。否则会变得更加毛茸茸。

我不同意你在进程中无法实现的其他海报。它应该可以很好地工作到某一点,不需要批处理作业。

答案 3 :(得分:0)

我认为你的servlet因硬盘速度而运行缓慢。如果文件列表是永久性的,则应将其加载到内存中