我必须想出一种方法来递归遍历目录并列出其中的所有文件和子目录文件。我非常确定我已经提出了一个可靠的方法来做到这一点,但是我需要一个文件数组来暂时保存当前目录中的文件和目录列表。 我的问题是,一旦程序再次调用自己,那个临时数组会被重写到现在打开的目录中的文件和目录列表中,还是会创建某种新数组?
代码尚未完成,我只是将其包含在内,以便了解我正在使用的内容。当一个子目录存在时再次调用临时数组时程序是否仍然具有临时数组,当它最终遍历回第一个调用时? 如果没有,我该怎么做才能解决这个问题?我考虑过创建一个列表,但是在类型转换方面遇到了麻烦。
private void enumerateDirectory(File f)
{
if(f.isDirectory()){
File[] temp = f.listFiles();
for(int i = 0; i<temp.length; ++i){
if(temp[i].isDirectory()){
enumerateDirectory(temp[i]);
}
else{
items[i].add(temp[i]);
}
}
}
else{
//error message to go here
}
}
答案 0 :(得分:2)
每次方法递归时,它就好像是一个全新的方法调用 - 你永远不必担心变量名冲突,因为你只能访问当前方法执行中的变量。例如,
public void a() {
int v = 1;
b();
}
public void b() {
// can't access v;
}
方法b()
无法访问变量v
。对您来说情况相同,除了a()
调用b()
而不是enumerateDirectory()
调用自己。
此外,编译程序时会丢弃局部变量名,并将它们替换为堆栈上的偏移量。在这种情况下,它是一个指向数组的指针,因此它只是每个帧中的一个小指针引用。
修改强>:
但是,items
中的元素将被覆盖,因为它不是局部变量。我不确定这是不是你想要的。每次方法对items
起作用时,内容都保持不变,因为它是您班级中的一个字段(我猜不到,因为我没有在代码中看到它)。这意味着如果a()
填充null
s,那么当b()
到达那里时,null
仍然存在。
答案 1 :(得分:0)
当进行递归调用时,该方法克隆自身,制作以下新副本: 代码,局部变量(及其初始值)和参数。
在第一次调用的情况下,将所有文件保存在数组temp中(如果f是目录):
File[] temp = f.listFiles();
然后迭代文件中的temp和每个文件再次调用方法递归传递文件的名称。现在我们有了一个方法的新副本,其中传递的文件将是方法的参数f
。当此方法副本结束时,控件将在循环后返回到下一个语句。
如果存在子目录,则再次调用temp数组时 程序在最终遍历时仍然具有临时数组 第一个电话? 是的,它会。