1

私のプログラムは、コンピューター (OS Ubuntu) 上のファイルへのすべてのパスを 1 つのMapに収集します。Mapのキーはファイル サイズで、値はファイルへの正規パスのリストで、サイズはキーと同じです。

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 ~ 1000 個以上のファイルを入力し、そこからスキャンを開始しました。すべて正常に動作します。

プログラムが 30 万ファイル未満のルート ディレクトリ "/" から起動すると例外が発生するのはなぜですか? これを防ぐにはどうすればよいですか?

4

3 に答える 3

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 に答える
1

最も可能性の高い説明は、サイクル (無限ループ) を作成するファイル システムのどこかにシンボリック リンクがあることです。たとえば、次はサイクルになります

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

ファイルのスキャン中は、ディレクトリへのシンボリック リンクを無視する必要があります。

于 2013-10-25T18:21:02.550 に答える