2

Being very new to Java, I'm unable to bring a small concept to a syntactic form. Apologies.

My project structure looks like below & i'm trying to walk thru the sub folders of applications directory & search for a folder named conduit, if present, create a new folder called base parallel to it.

At best I came up with the below code, post that, kind of struggling.

/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);

  }
 }
Chel MS
  • 386
  • 1
  • 10

2 Answers2

1

You can use BFS to traverse the sub directories:

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)); 
                }
            }
        }
    }
}
}
  • not that it is wrong, but what is the reasoning for using BFS? i think DFS would work just as well...for each folder, call recursively on each subfolder, until you find "conduit" and then create "base" and return. DFS is just easier to write. – Tom Elias Feb 03 '22 at 08:14
  • @TomElias yeah, it can be solved by both BFS and DFS, I just gave an example of BFS because I think it would be easier for a new java developer to understand quickly. – Shibbir Ahmed Feb 03 '22 at 08:28
  • @ShibbirAhmed : Really appreciate your help here.. Is it possible for you to explain what exactly `Queue paths = new LinkedList<>();` does and why we need this ? thanks again – Chel MS Feb 03 '22 at 08:44
  • @ChelMS, Queue<> is an interface in java which has the methods to implement the Queue Data Structure and LinkedList is one of the many implementation of Queue interface in java. (javadoc: https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html) We need a queue to implement BFS algorithm. – Shibbir Ahmed Feb 03 '22 at 08:58
  • @ShibbirAhmed: It works for the parent directory but incase of the folder `conduit` is present in sub directories its not working..what changes should I be making here, thanks – Chel MS Feb 07 '22 at 08:54
  • @ChelMS : just update the line inside the for loop from paths.add(Path.of(fileName)); to paths.add(Paths.get(currentFile.getAbsolutePath()+"/"+fileName)); Then it will work for all the sub directories.. – Shibbir Ahmed Feb 07 '22 at 16:08
  • @ChelMS I have updated the solution I answered before, you can use the solution without any change.. This is working for sub-directories.. – Shibbir Ahmed Feb 08 '22 at 12:42
  • @Shibbir Ahmed : Really appreciate your help here !! `file.mkdir()` dont take arguments, but my requirement is when `conduit` folder is spotted , `base` folder has to be created along side to `conduit`, so I tried the below in the if loop `File newDir = new File("base"); newDir.mkdir()` and this is not working.. Could you please correct me here, thanks a lot again – Chel MS Feb 08 '22 at 14:30
  • 1
    @ChelMS you have to put the absolute path of the file to create it. Thus, your base directory creation should look like: File newDir = new File(current.getParent()+"/base"); newDir.mkdir(); – Shibbir Ahmed Feb 08 '22 at 17:39
  • thanks a lot @ShibbirAhmed .. Really appreciate the support.. – Chel MS Feb 08 '22 at 18:12
1

Using Files.find is a good way to traverse a series of directories quickly to find files or directories matching any criteria you need. Here is an example which prints off the matches:

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"));
        }
    );
}
DuncG
  • 12,137
  • 2
  • 21
  • 33
  • I'm getting below errors, what am I doing incorrect ? `test.java:9: error: cannot find symbol BiPredicate predicate = (p,a) -> a.isDirectory() && "conduit".equals(p.getFileName().toString()); ^ symbol: class BiPredicate location: class test test.java:9: error: cannot find symbol BiPredicate predicate = (p,a) -> a.isDirectory() && "conduit".equals(p.getFileName().toString()); ^ symbol: class BasicFileAttributes location: class test` – Chel MS Feb 03 '22 at 10:18
  • `import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; public class test { public static void main(String[] args) { BiPredicate 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")); } ); } } }` – Chel MS Feb 03 '22 at 10:19
  • Just replace `predicate` by its definition `(p,a) -> a.isDirectory() && "conduit".equals(p.getFileName().toString())` in the final parameter of `Files.find`, then you don't need to import `BiPredicate` and `BasicFileAttributes` – DuncG Feb 03 '22 at 17:20
  • I imported `import java.nio.file.attribute.BasicFileAttributes; and import java.util.function.BiPredicate;` but now facing below error.. `10: error: cannot find symbol try(var dirs = Files.find(Path.of("."), Integer.MAX_VALUE, predicate)) { ^ symbol: class var location: class one` – Chel MS Feb 03 '22 at 18:22
  • You are using an old JDK, upgrade to newer JDK or try replacing `var` by `Stream`. – DuncG Feb 03 '22 at 18:57
  • Cool, thank you !! – Chel MS Feb 04 '22 at 04:33