***问题***我需要编写一个简单的软件,在给定一定的约束条件下,将一系列文件附加到一个列表中。用户可以在两种“类型”的目录中进行选择:一种是带有***通配符的,表示它还应该浏览子目录;另一种是不带通配符的经典方法,它只获取该目录中存在的文件。
"我在做什么"
现在我在做一件最愚蠢的事
import java.io.File;
public class Eseguibile {
private static void displayIt(File node){
System.out.println(node.getAbsoluteFile());
if(node.isDirectory()){
String[] subNote = node.list();
for(String filename : subNote){
displayIt(new File(node, filename));
}
}
}
public static void main(String[] args){
System.out.println("ciao");
displayIt( new File("/home/dierre/") );
}
}
我不需要建立一个树,因为我只需要文件列表,所以我想也许有一个更有效的方法来做到这一点。
我阅读了关于TreeModel的内容,但据我所知,它只是一个实现Jtree的接口。
8条答案
按热度按时间qyswt5oh1#
现在我正在做一件最愚蠢的事...
递归既不“愚蠢”,也不一定是低效的。实际上,在这种特殊情况下,递归解决方案可能比非递归解决方案更有效。当然,递归解决方案比其他解决方案更容易编码和理解。
递归的唯一潜在问题是,如果目录树太深,堆栈可能会溢出。
如果你真的想避免递归,那么最自然的方法就是使用“文件列表堆栈”数据结构。(剩余)将对象归档到堆栈中,读取新目录并开始处理它们。完成后,弹出堆栈并继续父目录。这将给予你一个深度优先遍历。如果你想要一个广度优先遍历,使用“文件队列”数据结构而不是堆栈。
o2gm4chl2#
我的迭代解决方案:
ippsafx73#
如果有帮助的话,这里有一个C#版本的迭代文件系统遍历:
@Stephen C:下面按照你的要求,我的基准代码,我在评论中谈到(C# -不是Java).
请注意,它应该使用秒表,而不是日期时间,以获得更好的准确性,但除此之外,它的罚款。
我没有测试迭代是否提供了与递归相同数量的文件,但它应该提供。
实际上,如果您注意一下中间值,您会注意到这已经开始显示只有很少的文件。(我的桌面文件夹包含2210个文件,415个文件夹,总共3.2 GB,其中大部分是下载文件夹AppData中的大文件,由于我的桌面上有一个较大的C#项目[mail-server],因此文件数量更多)。
要得到我在评论中提到的数字,安装cygwin(所有的东西[我想大约是100 GB]),并索引cygwin文件夹。
正如评论中提到的,说没关系并不完全正确。
而对于一个小的目录树,递归比迭代效率高得多,可以忽略不计(以几十毫秒的数量级),对于一个非常大的树,递归是分钟如果你必须分配并返回一组新的堆栈变量,那么每次调用一个函数,并存储所有先前的结果,直到你返回为止,当然,这要比在堆上初始化一个堆栈结构并在每次迭代中使用它慢。
树并不需要病理学上的深度来注意这种效果(虽然速度慢不是堆栈溢出,但它的负面后果与StackOverflow-Bug没有太大区别).我也不会把拥有大量文件称为“病态,”因为如果你在主驱动器上创建索引,你自然会拥有大量文件.有一些HTML文档,并且文件的数量爆炸式增长,你会发现对于大量的文件,一次迭代不到30秒就完成了,而一次递归需要大约3分钟。
如果需要保留遍历顺序,简化版本如下:
ct3nt3jp4#
递归总是可以转换成循环。
一个快速且不明确的可能解决方案(未测试)如下:
请注意源节点应该是要显示的任何内容的目录。
另外,这是一个广度优先显示。如果你想要一个深度优先,你应该改变“append”,把文件放在数组列表中当前节点的后面。
不过,我不确定记忆是否会消失。
此致
纪尧姆
r7s23pms5#
如果您选择使用递归,我找到了一个可能与您当前使用的示例非常接近的示例,以消除任何歧义。
这是一个非常简单的例子,
process()
可以是你对目录进行处理或操作的地方。ryevplcw6#
我是一个真实的的新手,但是在这个问题上工作了一个星期之后...我有了一个干净的解决方案...感谢Patry和etbal的所有帮助。
zxlwwiss7#
PARTY,谢谢你的建议。我对你的代码做了一点修改,这就是我所得到的
0qx6xfy68#
基于PATRY Guillaume解决方案