2017-10-03 4 views
-1

Étant donné la classe FileRepository ci-dessous, comment puis-je optimiser la recherche de fichiers car j'ai affaire à 500 annuaires clients ou plus. Peut-être que je peux réécrire le ci-dessous en utilisant Streams?trouver le modèle correspond à des fichiers de façon récursive

J'ai besoin de regarder tous les répertoires de clients au premier niveau, puis pour chaque répertoire client regardez un niveau ci-dessous et ne prend en compte que le dossier d'hier qui est quelque chose comme COB02Oct2010. J'ai écrit un DateHelper pour me renvoyer cette date du jour ouvrable précédent pour ensuite considérer seulement les sous-répertoires qui sont pertinents ... puis je regarde le modèle de fichier correspondant qui réside dans ce répertoire pour obtenir le fichier à envoyer. Puis-je simplement utiliser Paths et DirectoryStream?

public class FileRepository { 

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

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

     File[] customerDir = 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); //add a "." 

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

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

Je ne sais pas comment je peux écrire un filtre peut-être par exemple comme ceci:

try (DirectoryStream<Path> stream = Files.newDirectoryStream(directoryPath, filter)) { 
      for (Path path : stream) { 
       if (Files.isRegularFile(path)) { 
        consumer.accept(path); 
       } 
      } 
} 

Répondre

0

Voici une solution d'échantillon par ma bibliothèque: AbacusUtil

public List<File> getFilesToSend(String sourcePath, String pattern, String format) { 
    final Predicate<File> isTargetFile = f -> f.isFile() 
           && N.startsWithIgnoreCase(f.getName(), pattern) 
           && N.endsWithIgnoreCase(f.getName(), "." + format); 

    return Stream.list(new File(sourcePath)) 
      .filter(File::isDirectory) 
      .map(f -> new File(f, "COB" + getPreviousWorkingDay())) 
      .flatMap(cobDir -> Stream.list(cobDir, true).filter(isTargetFile)) 
      .toList(); 
}