递归查找目录基于模式

问题描述:

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

有许多clientfolders和人的结构y COBddmmyyyy文件夹。

比方说,我已经有了一个方法,给我的玉米棒文件夹名称。

如何找到所有客户机文件夹的所有匹配的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; 
    } 
+0

那么,在这个例子中,你想要所有'COB03Oct2017'文件夹位于父'sourcefolder'和不同'clientfolders'下? – procrastinator

+0

@procrastinator yes - 首先获取源代码下的所有客户端文件夹,然后查找COB文件夹。目的是只在最新的COB文件夹中查找文件,因为我正在处理一个非常大的目录树。 – user2781389

+0

提供的代码是否按预期工作? – c0der

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

我有以下的,但它是一种缓慢的。任何关于改进的建议?

这是我试图找到您的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")。我认为这应该工作。

干杯。

另一种方法可以是递归的方法,将挖出深达需要找到指定的文件夹:

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