【问题标题】:error while listing files in a directory列出目录中的文件时出错
【发布时间】:2011-11-16 06:23:44
【问题描述】:

我有一个 java 类用于列出给定目录的文件。它适用于只有文件而没有子目录的目录。但是如果里面有子目录,就会给出 java.lang.StackOverflowError 异常。这是类以及 main() 方法:

package test;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class DisplayFilesAndFolders {

    public static void main(String[] args) {
        try {
            List<File> files = getFileList();
            for(File file : files ){
              System.out.println(file);
            }
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static List<File> getFileList() throws FileNotFoundException{
        String sPath = "C:\\Users\\owner\\Desktop\\Screen Shot\\";
        File filePath = new File(sPath);
        List<File> fileList = new ArrayList<File>();
        File[] files = filePath.listFiles();
        List<File> fileandFolderList = Arrays.asList(files);
        for (File file : fileandFolderList) {
            fileList.add(file);
            if (file.isDirectory()) {
                List<File> innerFileList = getFileList();
                fileList.addAll(innerFileList);
            }
        }

        return fileList;

    }

}

感谢您的宝贵时间。

【问题讨论】:

    标签: java file


    【解决方案1】:

    您需要将getFileList 搜索的根作为参数,并在每次递归时将子目录作为参数传递。 (目前,您在每个递归调用中都从 C:\Users\owner\Desktop\Screen Shot\ 重新开始。)

    尝试以下方法(它在我的系统上按预期工作):

    public class Test {
    
        public static void main(String[] args) {
            try {
                String root = "C:\\Users\\owner\\Desktop\\Screen Shot\\";
                List<File> files = getFileList(new File(root));
                for(File file : files ){
                    System.out.println(file);
                }
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    
        public static List<File> getFileList(File filePath)
                throws FileNotFoundException{
    
            List<File> fileList = new ArrayList<File>();
            File[] files = filePath.listFiles();
            List<File> fileandFolderList = Arrays.asList(files);
            for (File file : fileandFolderList) {
                fileList.add(file);
                if (file.isDirectory()) {
                    List<File> innerFileList = getFileList(file);
                    fileList.addAll(innerFileList);
                }
            }
    
            return fileList;
        }
    }
    

    【讨论】:

    • 永远记住,如果你使用递归,你必须有一个定义的停止点。这通常由传递给递归方法的参数决定。如果您有一个不带任何参数的递归方法,那么您可能遇到了问题。
    • 同意!起初我的 getFileList() 有一个 String 参数,但后来我认为如果我在类中添加一个 main() 方法对用户回答会有帮助,从长远来看,我在递归方法中对其进行了硬编码...... :-(
    • @aioobe 既然你过去帮助过我,我请求你看看我的另一个问题。它与此无关。 stackoverflow.com/q/8937158/778687
    • @JohnB,你也是。请看看我的另一个问题(与此无关)stackoverflow.com/q/8937158/778687
    【解决方案2】:

    我之前已经实现了类似你的方法的东西,也得到了 StackOverflowException,因为我没有检查文件是否是符号链接。如果在指向目录的符号链接上调用isDirectory,它将返回true。因此,您将遵循可以指向任何地方的符号链接,可能会导致无穷无尽的树遍历,从而导致 StackOverflowException。

    【讨论】:

    • 你能举个“符号链接”的例子吗?
    • unix> man ln 查找 -s 标志。当你“ls -l”时,它们看起来像这样:a --> some/other/dir/a 箭头是关键。
    • 一篇介绍如何在 Windows 中创建符号链接以便您了解代码如何处理它们的文章:windows7home.net/how-to-create-symbolic-link-in-windows-7
    • @Phoenix 和 Oliver Weiler,请您看看我的另一个问题(与此无关)。我需要你们的帮助。谢谢你的时间。 stackoverflow.com/q/8937158/778687
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-09
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 2013-08-30
    • 2012-03-22
    相关资源
    最近更新 更多