基于模式递归查找目录

时间:2017-10-04 07:21:32

标签: java file file-io nio

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

如上所述,或使用Apache IO或Java NIO,我如何递归查找符合以下模式的目录:

  

COB03Oct2017(基本上类似于上一个工作日)

我的结构类似于/sourcefolder/clientfolders/COB03Oct2017/file.pdf

有许多客户端文件夹和许多 COBddmmyyyy 文件夹。

我们说我已经有一个方法可以给我一个cob文件夹名称。

如何找到所有客户端文件夹的所有匹配的cob文件夹?

    @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;
    }

以上是我的尝试。但是在你的帮助下,我想知道我做错了什么,怎么写得更好等等。

这一点也奏效了。但这又能改善吗?如何忽略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;
    }

3 个答案:

答案 0 :(得分:0)

这是我试图在SourceFolder中找到特定文件夹的内容。我使用过Java 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");
            }
        });

      }
  }

}

这将返回包含字符串"YourString"的所有文件夹作为名称。如果您想将名称与正则表达式匹配,则需要将方法.equalsIgnoreCase("YourString")更改为.matches("YourRegex")。我认为这应该有效。

干杯。

答案 1 :(得分:0)

另一种方法可以是递归方法,可以根据需要深入挖掘以找到指定的文件夹:

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

答案 2 :(得分:0)

public List<File> getFilesToSend(String sourcePath, String pattern, String format) {

    List<File> files = new ArrayList<>();

    File[] clientDirs = getCustomerDirs(sourcePath);

    for (int i = 0; i < clientDirs.length; i++) {
        files.addAll(processClientDirectory(clientDirs[i], pattern, format));
    }

    return files;
}

private List<File> processClientDirectory(File clientDir, String pattern, String format) {

    List<File> result = new ArrayList<>();

    pattern = pattern.toLowerCase(Locale.ENGLISH);
    format = Constants.EXTENSION_SEPARATOR + format.toLowerCase(Locale.ENGLISH);

    File cobDir = new File(clientDir, "COB" + DateHelper.getPreviousWorkingDay());
    getFilesToProcess(result, cobDir, pattern, format);

    return result;
}

private void getFilesToProcess(List<File> result, File cobDir, String pattern, String format) {


    if (!cobDir.exists()) {
        return;
    }

    File[] files = cobDir.listFiles(pathName -> {
        if (pathName.isDirectory()) {
            return true;
        }

        if (!pathName.isFile()) {
            return false;
        }

        String name = pathName.getName().toLowerCase(Locale.ENGLISH);
        if (!name.startsWith(pattern)) {
            return false;
        }
        if (!name.endsWith(format)) {
            return false;
        }

        return true;
    });

    for (int i = 0; i < files.length; i++) {
        File current = files[i];
        if (current.isDirectory()) {
            getFilesToProcess(result, current, pattern, format);
            continue;
        }
        result.add(current);
    }
}


private File[] getCustomerDirs(String sourcePath) {
    File[] directories = new File(sourcePath).listFiles(File::isDirectory);
    return directories;
}

我有以下内容,但它有点慢。有关改进的建议吗?