簡體   English   中英

找到樹中最深的文件/目錄,Java

[英]Find the deepest file/directory in the tree, Java

我有一個目錄( basedir3645 ),其中包含許多嵌套目錄和文件(近 40 000 個)。 每個嵌套目錄可能包含一些文件和目錄。 問題是找到最深的文件或目錄(該方法必須返回最深項的嵌套級別及其名稱/路徑。

import java.io.File;

public class Main {

    public static void main(String[] args) {
        String pathToDir = "D:\\Dropbox\\java\\tasks\\basedir3645";
        File baseDir = new File(pathToDir);
        System.out.println(findDeepestItem(baseDir));   
    }

    static public String findDeepestItem(File folder) {
        int currentLevel = 0;
        int deepestLevel = 0;
        String deepestItem = "";
        String result = "";
        File[] folderEntries = folder.listFiles();
        for (File entry : folderEntries) {
            currentLevel = countMatches(entry.getPath(), "\\");
            if (entry.isDirectory()) {
                findDeepestItem(entry);
                if (deepestLevel < currentLevel) {
                    deepestLevel = currentLevel;
                    deepestItem = entry.getPath();
                }
                continue;
            } else {
                if (deepestLevel < currentLevel) {
                    deepestLevel = currentLevel;
                    deepestItem = entry.getPath();
                }
            }
        }
        result = String.valueOf(deepestLevel) + " " + deepestItem;
        return result;
    }

    private static int countMatches(String path, String string) {
        int number = 0;
        String[] array = path.split("");
        for (int i = 0; i < path.length(); i++) {
            if (string.contentEquals(array[i])) {
                number++;
            }
        }
        return number;
    }
}

在這里,我通過計算項目getPath()中的\出現次數來確定當前項目(文件或目錄)的嵌套級別。

該程序遍歷樹中的所有元素(我已經檢查過它,使用System.out.println("entry.getPath()");在循環中,但它無法計算他最深的嵌套級別。

我明白我的錯誤在哪里 - 變量deepestLeveldeepestItem必須是 static 並且屬於 class。

不要只返回最深項目的名稱,還要返回級別。 為此,您將不得不

  • 將當前級別傳遞給findDeepestItem
  • 返回包含名稱和級別的結果 object。
public class Main {

    String dirName = "";
    int deepFile = 0;
    int permDeep = 0;

    public String getFiles(File files) {
        for (File file : files.listFiles()) {
            if (file.isDirectory()) {
                permDeep++;
                getFiles(file);
                if (permDeep > deepFile) {
                    deepFile = permDeep;
                    dirName = file.getName();
                }
                permDeep--;
            } else {
                if (permDeep > deepFile) {
                    deepFile = permDeep;
                    dirName = file.getName();
                }
            }
        }
        return dirName;
    }
}
public static class Pair {
    int depth;
    String name;

    Pair(int depth, String name) {
        this.depth = depth;
        this.name = name;
    }
}

public static Pair depthFirstSearch(File root) {
    if(root.isFile() || root.listFiles().length == 0) {
        return new Pair(1, root.getName());
    }

    File[] files = root.listFiles();
    Pair maxForThisNode = new Pair(-1, "");
    for(int i = 0; i < files.length; i++) {
        Pair childPair = depthFirstSearch(files[i]);
        if(childPair.depth > maxForThisNode.depth) {
            maxForThisNode.depth = childPair.depth;
            maxForThisNode.name = childPair.name;
        }
    }

    maxForThisNode.depth += 1;
    return maxForThisNode;
}
public class Main {
    public static void main(String[] args) throws IOException {
        CompareHolder holder = new CompareHolder();
        Files.walk(Path.of(args[0]))
                .map(Path::toFile)
                .filter(File::isFile)
                .forEach(file -> holder.compare(file.getName(), file.getPath().split("/").length));
        System.out.printf("The longest depth is %d and the file name is %s %n", holder.depth, holder.name);
    }

    static class CompareHolder {
        String name;
        int depth;

        void compare(String name, int depth) {
            if (depth > this.depth) {
                this.depth = depth;
                this.name = name;
            }
        }
    }
}

下面是我的解決方案。 它類似於 denamyte 的答案,但沒有與java.io.File的對話。

我使用Files.walk()Path.getNameCount()方法來確定從給定路徑開始的最深文件。 s.map(p::relativize)確保忽略起始目錄的深度。

返回的 object 是java.nio.file.Path ,因此它提供了您應該需要的所有信息。

public class Main {

    public static void main(String[] args) throws Exception {
        Path p = Paths.get("C:\\anypath");
        Optional<Path> deepest = findDeepest(p);
        if (deepest.isPresent()) {
            Path pdeep = deepest.get();
            boolean isFile = Files.isRegularFile(p.resolve(pdeep));
            System.out.printf("level: %d, isfile: %s, path %s", pdeep.getNameCount() - (isFile ? 1 : 0), isFile, pdeep);
        } else
            System.err.println("no files found");
    }

    public static Optional<Path> findDeepest(Path p) throws IOException {
        try (Stream<Path> s = Files.walk(p)) {
            return s.filter(Files::isRegularFile).map(p::relativize).max(Comparator.comparing(Path::getNameCount));
        }
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM