【问题标题】:Java - traverse through folders and do something if intended folder is presentJava - 遍历文件夹并在存在预期文件夹时执行某些操作
【发布时间】:2022-02-03 07:38:24
【问题描述】:

作为 Java 新手,我无法将小概念带入句法形式。道歉。

我的项目结构如下所示,我正在尝试遍历 applications 的子文件夹 目录并搜索名为 conduit 的文件夹,如果存在,创建一个名为 base 的新文件夹,与其并行。

充其量我想出了下面的代码,贴出来,有点挣扎。

/home/project_A/applications
                |sub_project_A
                  |target
                    |conduit
                |sub_project_B
                  |target
                    |conduit

                |sub_project_C
                  |target
                    |class

                |sub_project_D
                  |target
                    |conduit    

public class Test
{

  public static void main(String[] args)
  {
    Path currentRelativePath = Paths.get("");
    String s = currentRelativePath.toAbsolutePath().toString();
    String appDir = s + "/applications";
    System.out.println("Directory Exists" + appDir);

  }
 }

【问题讨论】:

标签: java


【解决方案1】:

使用Files.find 是快速遍历一系列目录以查找符合您需要的任何条件的文件或目录的好方法。这是一个打印匹配项的示例:

BiPredicate<Path, BasicFileAttributes> predicate = (p,a) -> a.isDirectory() && "conduit".equals(p.getFileName().toString());
try(var dirs = Files.find(Path.of("."), Integer.MAX_VALUE, predicate)) {
    dirs.forEach(p -> {
            System.out.println("Found "+p+", create if not exists: "+p.resolveSibling("base"));
        }
    );
}

【讨论】:

  • 我遇到错误,我做错了什么? test.java:9: error: cannot find symbol BiPredicate&lt;Path, BasicFileAttributes&gt; predicate = (p,a) -&gt; a.isDirectory() &amp;&amp; "conduit".equals(p.getFileName().toString()); ^ symbol: class BiPredicate location: class test test.java:9: error: cannot find symbol BiPredicate&lt;Path, BasicFileAttributes&gt; predicate = (p,a) -&gt; a.isDirectory() &amp;&amp; "conduit".equals(p.getFileName().toString()); ^ symbol: class BasicFileAttributes location: class test
  • import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; public class test { public static void main(String[] args) { BiPredicate&lt;Path, BasicFileAttributes&gt; predicate = (p,a) -&gt; a.isDirectory() &amp;&amp; "conduit".equals(p.getFileName().toString()); try(var dirs = Files.find(Path.of("."), Integer.MAX_VALUE, predicate)) { dirs.forEach(p -&gt; { System.out.println("Found "+p+", create if not exists: "+p.resolveSibling("base")); } ); } } }
  • 只需在Files.find的最后一个参数中将predicate替换为它的定义(p,a) -&gt; a.isDirectory() &amp;&amp; "conduit".equals(p.getFileName().toString()),则不需要导入BiPredicateBasicFileAttributes
  • 我导入了 import java.nio.file.attribute.BasicFileAttributes; and import java.util.function.BiPredicate; 但现在面临以下错误.. 10: error: cannot find symbol try(var dirs = Files.find(Path.of("."), Integer.MAX_VALUE, predicate)) { ^ symbol: class var location: class one
  • 您正在使用旧的 JDK,升级到新的 JDK 或尝试将 var 替换为 Stream&lt;Path&gt;
【解决方案2】:

可以使用BFS遍历子目录:

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.Queue;

public class MyClass {
public static void main(String[] args) {
    Path currentRelativePath = Paths.get("");
    Queue<Path> paths = new LinkedList<>();
    paths.add(currentRelativePath);
    while(!paths.isEmpty()) {
        Path current = paths.poll();
        File currentFile = current.toFile();
        if(currentFile.isDirectory()) {
            if(currentFile.getName().equals("conduit")) {
                // Found the directory called conduit, Do what you have to do here
            }else {
                for(String fileName : currentFile.list()) {
                    paths.add(Paths.get(currentFile.getAbsolutePath()+"/"+fileName)); 
                }
            }
        }
    }
}
}

【讨论】:

  • 不是说错了,而是使用BFS的理由是什么?我认为 DFS 也可以工作...对于每个文件夹,递归调用每个子文件夹,直到找到“管道”,然后创建“基础”并返回。 DFS 只是更容易编写。
  • @TomElias 是的,BFS 和 DFS 都可以解决,我只是举了一个 BFS 的例子,因为我认为它对于一个新的 java 开发人员来说会更容易快速理解。
  • @ShibbirAhmed :非常感谢您在这里的帮助。您是否可以解释一下 Queue&lt;Path&gt; paths = new LinkedList&lt;&gt;(); 的确切作用以及我们为什么需要它?再次感谢
  • @ChelMS, Queue 是 java 中的一个接口,它具有实现队列数据结构的方法,而 LinkedList 是 java 中 Queue 接口的众多实现之一。 (javadoc: docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html) 我们需要一个队列来实现 BFS 算法。
  • @CelMS 您必须输入文件的绝对路径才能创建它。因此,您的基本目录创建应如下所示: File newDir = new File(current.getParent()+"/base"); newDir.mkdir();
猜你喜欢
  • 1970-01-01
  • 2018-10-31
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
  • 2014-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多