1

我的程序将计算机(OS Ubuntu)上文件的所有路径收集到一个MapMap中的键是文件大小,值是文件的规范路径列表,大小等于键。

Map<Long, ArrayList<String>> map = new HashMap<>(100000);

计算机上的文件总数为:281091

一种收集文件的方法,它是递归的。

private void scanner(String path) throws Exception {

        File[] dirs = new File(path).listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {

                if (file.isFile() && file.canRead()) {

                    long size = file.length();

                    String canonPath = file.getCanonicalPath();

                    if (map.containsKey(size))
                        map.get(size).add(canonPath);

                    else map.put(size, new ArrayList<>(Arrays.asList(canonPath)));

                    return false;
                }
                return file.isDirectory() && file.canRead();
            }
        });

        for (File dir : dirs) {
            scanner(dir.getCanonicalPath());
        }
    }

当我开始从根文件夹“/”开始扫描时,出现异常:

Exception in thread "main" java.lang.StackOverflowError
    at java.io.UnixFileSystem.canonicalize0(Native Method)
    at java.io.UnixFileSystem.canonicalize(UnixFileSystem.java:172)
    at java.io.File.getCanonicalPath(File.java:589)
    at taskB.FileScanner.setCanonPath(FileScanner.java:49)
    at taskB.FileScanner.access$000(FileScanner.java:12)
    at taskB.FileScanner$1.accept(FileScanner.java:93)
    at java.io.File.listFiles(File.java:1217)
    at taskB.FileScanner.scanner(FileScanner.java:85)
    at taskB.FileScanner.scanner(FileScanner.java:109)
    at taskB.FileScanner.scanner(FileScanner.java:109)
    ...

但为了测试,我填写了目录“~/Documents”超过400 ~ 千个文件并开始从中扫描。一切正常。

为什么当程序从根目录“/”开始时,少了30万个文件我有异常?我应该怎么做才能防止这种情况发生?

4

3 回答 3

1

The most likely explanation is that you have a symbolic link somewhere in the filesystem that creates a cycle (an infinite loop). For example, the following would be a cycle

  /home/userid/test/data -> /home/userid

While scanning files you need to ignore symbolic links to directories.

于 2013-10-25T18:21:02.550 回答
1

@Jim Garrison 是对的,这是由于符号链接。解决我在这里发现的问题。

我使用isSymbolicLink(Path)方法。

return file.isDirectory() && file.canRead() && !Files.isSymbolicLink(file.toPath());
于 2013-10-26T20:47:22.287 回答
1

StackOverflow 意味着您调用了如此多的嵌套函数,以至于您的程序的内存空间用于函数调用信息(从调用返回后保留)。在您的情况下,我怀疑这是由于解析“。” (当前目录)和“..”(父目录)条目在目录列表中返回时,因此您多次递归到同一个目录。

于 2013-10-25T18:20:38.607 回答