java.lang.StackOverflowerr递归目录

java.lang.StackOverflowerr递归目录,java,android,stack-overflow,Java,Android,Stack Overflow,在我的Android应用程序中,我将外部存储的所有路径填充到一个数组中 少数设备报告出现故障 我已经阅读了关于这个问题的原因的文章,但是我不知道如何处理它或者如何防止它在我使用的代码中发生。我也不理解Android可以处理的“递归限制” 下面的代码经过改编 在某个地方,我需要计算递归并应用一个限制。但我不知道安卓或个人设备硬件的应用范围或限制 提前感谢您的帮助。计算递归很简单:只需在getFileListingNoSort方法中添加一个int参数,并在每次调用时增加值: private List

在我的Android应用程序中,我将外部存储的所有路径填充到一个数组中

少数设备报告出现故障

我已经阅读了关于这个问题的原因的文章,但是我不知道如何处理它或者如何防止它在我使用的代码中发生。我也不理解Android可以处理的“递归限制”

下面的代码经过改编

在某个地方,我需要计算递归并应用一个限制。但我不知道安卓或个人设备硬件的应用范围或限制


提前感谢您的帮助。

计算递归很简单:只需在
getFileListingNoSort
方法中添加一个
int
参数,并在每次调用时增加值:

private List<File> getFileListingNoSort(File aStartingDir, int level) {
    List<File> resultArray = new ArrayList<File>();
    File[] filesAndDirs = aStartingDir.listFiles();

    if (level < MAX_LEVEL && filesAndDirs != null && filesAndDirs.length > 0) {

        List<File> filesDirs = Arrays.asList(filesAndDirs);

        for (File file : filesDirs) {
            if (!file.isFile() && file.canRead() && !file.isHidden() && !file.getName().toLowerCase(loc).startsWith(CACHE)
                    && !file.getName().toLowerCase(loc).startsWith(TEMP)) {

                resultArray.add(file);
                List<File> deeperList = getFileListingNoSort(file, ++level);
                resultArray.addAll(deeperList);
            }
        }
    }

    return resultArray;
}
private List getFileListingNoSort(文件aStartingDir,int级别){
List resultArray=new ArrayList();
File[]filesAndDirs=aStartingDir.listFiles();
if(level0){
List filesDirs=Arrays.asList(filesAndDirs);
for(文件:filesDirs){
如果(!file.isFile()&&file.canRead()&&!file.ishiden()&&!file.getName().toLowerCase(loc).startWith(缓存)
&&!file.getName().toLowerCase(loc.startsWith(TEMP)){
添加(文件);
List deeperList=getFileListingNoSort(文件,++级别);
结果:addAll(deeperList);
}
}
}
返回结果数组;
}

但问题仍然是:对于MAX_LEVEL,什么是最佳值?为什么它会独立循环。所讨论的文件系统可能有创建循环的符号链接。

Android运行在许多硬件上,其中许多可能根本没有太多堆栈;不要在子目录中递归,而是进行广度优先搜索,因此:

private List<File> getFileListingNoSort(File aStartingDir) 
{
    // assuming aStartingDir is a valid input
    List<File> dirsToSearch = new ArrayList<File>();
    dirsToSearch.add(aStartingDir);
    List<File> resultArray = new ArrayList<File>();
    do{
        File thisDir = dirsToSearch.remove(0);      
        List<File> filesDirs = Arrays.asList(thisDir.listFiles());

        for (File file : filesDirs) 
        {
            if (file.isDirectory())
            {
                dirsToSearch.add(file);
            }
             else if( file.canRead() && 
                      !file.isHidden() &&     
                      !file.getName().toLowerCase(loc).startsWith(CACHE) &&
                      !file.getName().toLowerCase(loc).startsWith(TEMP))
            {
                resultArray.add(file);              
            }
        }
    } while(false == dirsToSearch.isEmpty());
    return resultArray;
}
private List getFileListingNoSort(文件aStartingDir)
{
//假设aStartingDir是有效的输入
List dirsToSearch=new ArrayList();
dirsToSearch.add(aStartingDir);
List resultArray=new ArrayList();
做{
文件thisDir=dirsToSearch.remove(0);
List filesDirs=Arrays.asList(thisDir.listFiles());
for(文件:filesDirs)
{
if(file.isDirectory())
{
dirsToSearch.add(文件);
}
else if(file.canRead()&&
!file.ishiden()&&
!file.getName().toLowerCase(loc).startsWith(缓存)&&
!file.getName().toLowerCase(loc.startsWith(TEMP))
{
添加(文件);
}
}
}while(false==dirsToSearch.isEmpty());
返回结果数组;
}
注意:我没有运行,甚至没有查看这段代码是否可以编译

但想法是,维护一个目录列表,从您关心的目录开始,从该列表中删除第一个目录,将该目录中的文件添加到结果中(如果您也需要目录,请修改代码以将目录添加到resultArray),将目录添加到要搜索的目录列表中,然后继续,直到目录列表为空


如果你不能提前知道你必须递归到什么程度,或者你能递归到什么程度,那么递归是不好的。我不认为文件系统迭代适合递归,但这是我自己的观点。

谢谢Andreas。是的,问题仍然是这个限制应该设置为什么?此外,我也看到过一些帖子,其中超过了“最大整数级别”,应该使用long。在不知道限制的情况下,我不知道这是否也需要考虑?不太可能,可能是因为计数是存储路径。谢谢你指出这些象征性的联系——我没有考虑到这一点。我会调查的。谢谢Ben,但我有点困惑-“维护目录列表”,当在迭代文件dir的过程中,你遇到一个目录,你把它添加到dirsToSearch;否则,您将检查它是否符合您的条件,如果符合,则将其添加到resultsArray。只要存在已添加但未列出的目录,do…while循环就会继续,列出目录的第一步是将其从目录搜索中删除。我需要一点时间来消化您建议的实现。谢谢你回来澄清。
com.mypackage.name.GenerateSubDirectoryList -> com.mypackage.name.ll:
java.util.List getFileListingNoSort(java.io.File) -> a
private List<File> getFileListingNoSort(File aStartingDir, int level) {
    List<File> resultArray = new ArrayList<File>();
    File[] filesAndDirs = aStartingDir.listFiles();

    if (level < MAX_LEVEL && filesAndDirs != null && filesAndDirs.length > 0) {

        List<File> filesDirs = Arrays.asList(filesAndDirs);

        for (File file : filesDirs) {
            if (!file.isFile() && file.canRead() && !file.isHidden() && !file.getName().toLowerCase(loc).startsWith(CACHE)
                    && !file.getName().toLowerCase(loc).startsWith(TEMP)) {

                resultArray.add(file);
                List<File> deeperList = getFileListingNoSort(file, ++level);
                resultArray.addAll(deeperList);
            }
        }
    }

    return resultArray;
}
private List<File> getFileListingNoSort(File aStartingDir) 
{
    // assuming aStartingDir is a valid input
    List<File> dirsToSearch = new ArrayList<File>();
    dirsToSearch.add(aStartingDir);
    List<File> resultArray = new ArrayList<File>();
    do{
        File thisDir = dirsToSearch.remove(0);      
        List<File> filesDirs = Arrays.asList(thisDir.listFiles());

        for (File file : filesDirs) 
        {
            if (file.isDirectory())
            {
                dirsToSearch.add(file);
            }
             else if( file.canRead() && 
                      !file.isHidden() &&     
                      !file.getName().toLowerCase(loc).startsWith(CACHE) &&
                      !file.getName().toLowerCase(loc).startsWith(TEMP))
            {
                resultArray.add(file);              
            }
        }
    } while(false == dirsToSearch.isEmpty());
    return resultArray;
}