【问题标题】:Find the deepest file/directory in the tree, Java查找树中最深的文件/目录,Java
【发布时间】:2019-09-23 09:29:51
【问题描述】:

我有一个目录 (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()");,但它无法计算他最深的嵌套级别。

【问题讨论】:

  • 您不能使用java.nio 尤其是Path.getNameCount() 来确定文件树中文件系统对象的深度级别吗?也许使用java.nio.file.SimpleFileVisitor 来遍历文件树。

标签: java file nested


【解决方案1】:

我明白我的错误在哪里 - 变量 deepestLeveldeepestItem 必须是静态的并且属于类。

【讨论】:

    【解决方案2】:

    不要只返回最深项目的名称,还要返回级别。为此,您将不得不

    • 将当前级别传递给findDeepestItem
    • 返回一个包含名称和级别的结果对象。

    【讨论】:

      【解决方案3】:
      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;
          }
      }
      

      【讨论】:

        【解决方案4】:
        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;
        }
        

        【讨论】:

          【解决方案5】:
          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;
                      }
                  }
              }
          }
          

          【讨论】:

          • 添加一些解释来说明您显示的代码如何解决问题,以及它如何优于(或不同于)其他答案将显着改善这篇文章。
          【解决方案6】:

          在我的解决方案之下。它类似于 denamyte 的答案,但没有与 java.io.File 的对话。

          我使用Files.walk()Path.getNameCount() 方法来确定从给定路径开始的最深文件。 s.map(p::relativize) 确保忽略起始目录的深度。

          返回对象是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));
                  }
              }
          
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-07-15
            • 2018-04-01
            • 2015-05-04
            • 2016-02-16
            • 1970-01-01
            • 1970-01-01
            • 2021-01-12
            • 1970-01-01
            相关资源
            最近更新 更多