-1
public static printFnames(String sDir) {
    Files.find(Paths.get(sDir), 999, (p, bfa) -> bfa.isRegularFile()).forEach(System.out::println);
}

Given something like above, or using Apache IO or Java NIO, how can I recursively look for directory that match the following pattern:

COB03Oct2017 (which resembles last working day basically)

I have a structure like /sourcefolder/clientfolders/COB03Oct2017/file.pdf

There are many clientfolders and many COBddmmyyyy folders.

Let's say I have already got a method that gives me the cob folder name.

How can I find all matching cob folders for all client folders?

    @Test
    public void testFiles() {

        String sourcePath = "C:\\sourcepath\\";

        String cobPattern = "COB" + DateHelper.getPreviousWorkingDay();

        List<Path> clientDirectories = null;

        try {
            clientDirectories = Files.find(Paths.get(sourcePath), 1,
                    (path, bfa) -> bfa.isDirectory())
                    .collect(Collectors.toList());
        } catch (IOException e) {
            e.printStackTrace();
        }

        List<Path> cobDirectories = getCobDirectories(clientDirectories, cobPattern);

    }

    private List<Path> getCobDirectories(List<Path> clientDirectories, String cobPattern) {

        List<Path> collect = new ArrayList<>();

        clientDirectories
                .stream()
                .forEach(path -> {
                    try {
                     collect.addAll(Files.find(Paths.get(path.toString()), 1,
                                (p, bfa) -> bfa.isDirectory()
                                        && p.getFileName().toString().equals(cobPattern)).collect(Collectors.toList()));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });

        System.out.println("Done");
        return collect;
    }

The above is my attempt. But with your help, I would like to know if I am doing anything wrong, how it can be written better etc

This bit also worked. But again can this be improved? How do ignore exceptions such AccessDenied

    @Test
    public void testFiles() {

        String sourcePath = "\\\\server\\pathToCustomerReports\\";

        String cobPattern = "COB" + DateHelper.getPreviousWorkingDay();

        List<Path> clientDirectories = null;

        try {
            clientDirectories = Files.find(Paths.get(sourcePath), 1,
                    (path, bfa) -> bfa.isDirectory())
                    .collect(Collectors.toList());
        } catch (IOException e) {
            e.printStackTrace();
        }


        List<Path> cobDirectories = new ArrayList<>();

        clientDirectories.forEach(path -> cobDirectories.addAll(getCobdirs(path)));

        System.out.println("Done");


    }

    private List<Path> getCobdirs(Path path) {

        List<Path> cobDirs = new ArrayList<>();

        String cobPattern = "COB" + DateHelper.getPreviousWorkingDay();

        try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) {
            for (Path p : stream) {
                if (path.toFile().isDirectory() && p.getFileName().toString().equals(cobPattern)) {
                    cobDirs.add(p);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return cobDirs;
    }
M06H
  • 1,675
  • 3
  • 36
  • 76
  • So, in this example you want all the `COB03Oct2017` folders located under parent `sourcefolder` and different `clientfolders`? – Procrastinator Oct 04 '17 at 07:52
  • @procrastinator yes - first get all client folder under source, then find COB folders. Purpose is to look for files only in latest COB folder as I'm dealing with a very large directory tree. – M06H Oct 04 '17 at 08:01
  • Does the provided code work as expected ? – c0der Oct 04 '17 at 10:08
  • it does what I want it to do. However does throw `java.nio.file.AccessDeniedException` when one clientfolder is inaccessible. Could the above be re-factored or be made efficient further? – M06H Oct 04 '17 at 10:15
  • Do you want to scan all client directories ? or just some of them ? – c0der Oct 04 '17 at 10:28
  • need to scan all client directories that have Date Modified of today, which is almost all of them :), not so important though, but next level scan only last working day folder – M06H Oct 04 '17 at 10:30
  • Actually you can not avoid AccessDeniedException. You can see the further description [here](https://stackoverflow.com/questions/22867286/files-walk-calculate-total-size#answer-22868706) – Procrastinator Oct 04 '17 at 10:37
  • can ifnore directories with `clientDirectories = Files.find(Paths.get(sourcePath), 1, (path, bfa) -> bfa.isDirectory() && Files.isReadable(path)) .collect(Collectors.toList());` ? – M06H Oct 04 '17 at 10:54

2 Answers2

1

This is what I have tried to find the specific folder in your SourceFolder. I have used Java's file.fileList(filter)

public abstract class ChooseFile {

public static File parent = new File("your/path/name");

public static void main(String args[]) throws IOException {

    printFnames(parent.getAbsolutePath());
}

public static void printFnames(String sDir) throws IOException {

    // Take action only when parent is a directory
    if (parent.isDirectory()) {
        File[] children = parent.listFiles(new FileFilter() {
            public boolean accept(File file) {

                if (file.isDirectory() && file.getName().equalsIgnoreCase("YourString")) // I have serached for "bin" folders in my Source folder.
                    System.out.println(file.getAbsolutePath());
                else if (file.isDirectory())
                    try {
                        parent = file;
                        printFnames(file.getAbsolutePath());
                    }
                    catch (IOException exc) {
                        // TODO Auto-generated catch block
                        exc.printStackTrace();
                    }
                return file.isDirectory() || file.getName().toLowerCase().contains("YourString");
            }
        });

      }
  }

}

This would return all the folders which contains the string "YourString" as a name. In case, if you want to match the names with regex then you need to change the method .equalsIgnoreCase("YourString") to .matches("YourRegex"). I think that should work.

Cheers.

Procrastinator
  • 2,526
  • 30
  • 27
  • 36
1

An alternative approach can be a recursive method, that will dig as deep as needed to find the specified folder:

public static void main(String[] args) {

    //the directory to search. It will search the whole tree
    //so it should work also for sourcePath = "c:\\";
    String sourcePath = "c:\\sourcepath\\";
    String cobPattern = "COB03Oct2017";

    List<Path> cobDirectories = getCobDirectories(sourcePath, cobPattern);
    cobDirectories.forEach(p ->  System.out.println(p)); //check output
}

private static List<Path> getCobDirectories(String sourcePath, String cobPattern) {
    List<Path> cobDirs =  new ArrayList<>();
    getCobDirectories(sourcePath,cobPattern, cobDirs);
    return cobDirs;
}

private static void getCobDirectories(String sourcePath, String cobPattern, List<Path> cobDirs) {

    File file = new File(sourcePath);

    if( ! file.isDirectory()) {//search only in folders 
        return;
    }

    if(file.getName().equals(cobPattern)) {//add to collection 
        cobDirs.add(Paths.get(sourcePath));
        return;
    }

    if(file.list() == null) {//for abstract path or errors 
        return;
    }

    for (String fileName: file.list() ){

        getCobDirectories((sourcePath+"\\"+fileName),cobPattern, cobDirs);
    }
}
c0der
  • 18,467
  • 6
  • 33
  • 65