2016-04-11 1 views
1

Ich versuche, die Liste der Dateien in einem Array aus einem Stammverzeichnis und den Unterverzeichnissen innerhalb des Stammverzeichnisses zu erhalten. Betrachte C:\ als mein Root-Verzeichnis. Ich möchte auch die Liste von C:\abc und C:\def nach einem bestimmten Muster von Dateinamen erhalten. Hier ist der Code, den ich ausprobiert habe.Nested accept(), um Dateien im Unterverzeichnis in einem String-Array zu erhalten

public String[] getFilesList(File path){ 
     String[] filesList = null; 
     final String[] directories = null; 
     try { 
      properties.load(new StoricoPV_ISAU().getFile()); 
     } catch (IOException e) { 
      log.error(e.getMessage()); 
      e.printStackTrace(); 
     } 
     filesList = path.list(new FilenameFilter() { 
      public boolean accept(File dir, String name) { 
       if(name.matches(Constants.INTERNA_REGEX)){ 
        return true; 
       }else if(name.matches(Constants.SISS_REGEX)){ 
        return true; 
       }else if(new File(properties.getProperty(Constants.PATH_NAME)+name).isDirectory()){ 
        //error here: The final local variable directories cannot be assigned, since it is defined in an enclosing type 
        directories = new File(properties.getProperty(Constants.PATH_NAME)).list(new FilenameFilter() { 
         public boolean accept(File dir, String name) { 
          if(name.matches(Constants.INTERNA_REGEX)){ 
           return true; 
          }else if(name.matches(Constants.SISS_REGEX)){ 
           return true; 
          }else{ 
           log.info("Invalid file or directory: "+name); 
           return false; 
          } 
         } 
        }); 

        return false; 
       } 
       return false; 
      } 
     }); 

     return filesList; 
    } 

Okay, ich weiß, dass die Variable directories nicht final sein kann, aber zur gleichen Zeit, muss es final sein innerhalb dieser Methode zu arbeiten. Wie kann ich meine Logik ändern, so dass schließlich die Liste aller Dateien in C:\, C:\abc und C:\def in der Variablen filesList entsprechend dem angegebenen Dateimuster zurückgegeben wird. Jede Hilfe dazu wäre sehr geschätzt.

HINWEIS: Ich brauche nicht über Level 1 Tiefe im Verzeichnis zu bekommen. Zum Beispiel müssen wir jedes Verzeichnis innerhalb des Directories ignorieren C:\abc

Antwort

1

Das erste Ding in meiner Meinung ist Rekursion. Weil Sie nur auf Ebene Ordner benötigen, also füge ich eine Variable hinzu, um das zu steuern, wenn sich die Anforderung ändert.

public String[] getFilesList(File path) { 
    int deepth = 1; // Control the deepth of recursion 
    List<String> list = new ArrayList<String>(); 
    getFilesList(path, list, deepth); 
    return list.toArray(new String[list.size()]); 
} 

public void getFilesList(File path, final List<String> list, int deepth) { 
    if (deepth >= 0) { 
     final int newDeepth = deepth - 1; 
     String[] subList = path.list(new FilenameFilter() { 

     @Override 
     public boolean accept(File dir, String name) { 
      File subFile = new File(dir.getAbsolutePath() + "/" + name); 
      if (subFile.isFile()) { 
       if (name.matches(Constants.INTERNA_REGEX)) { 
       return true; 
      } else if (name.matches(Constants.SISS_REGEX)) { 
       return true; 
      } else { 
       // log.info("Invalid file or directory: " + name); 
       return false; 
      } 
     } else { 
      getFilesList(subFile, list, newDeepth); 
     } 
     return false; 
     } 
    }); 

    list.addAll(Arrays.asList(subList)); 
    } 
} 
+0

Es schien, dass das Code-Format ein Problem hatte, tut mir leid. –

+0

Ich mag die Antwort! Es löst das Problem ziemlich gut! Vielen Dank. :) –

1

Kannst du nicht etwas einfacher wie diese verwenden? Es wird wieder nur die Dateinamen gefiltert (die Regex passender und nur die erste Stufe des Ordners), wie Sie scheinen zu wollen:

public static void main(String[] args) { 
    List<String> fileNames = new ArrayList<>(); 
    File source = new File("C:\\Users\\mofh\\Desktop\\test"); 
    getFiles(fileNames, source, source); 
} 


public static void getFiles(List<String> fileNames, File dir, File parent) { 
    try { 
     File[] files = dir.listFiles(); 
     for (File file : files) { 
      if (file.isDirectory()) { 
       if (!file.getAbsolutePath().equals(parent.getAbsolutePath()) && 
         file.getParent().equals(parent.getAbsolutePath())) { 
        getFiles(fileNames, file, dir); 
       } 
      } else { 
       if (file.getName().matches(Constants.INTERNA_REGEX) || 
         file.getName().matches(Constants.SISS_REGEX)) { 
        fileNames.add(file.getCanonicalPath()); 
       } 
      } 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 
+0

Vielen Dank für die Lösung. Ich habe einen Flaschenhals, das ist Speicher. Weil ich mehr als 8000 Dateien in diesem Verzeichnis habe und ich versuche nur die Namen der Dateien und nicht die Dateien selbst zu bekommen. Ich möchte auch die Dateien ablehnen, die nicht mit meinem Muster übereinstimmen, so dass ich die Liste der Dateien reduzieren kann, die ich schließlich bekomme. Ich habe gerade einen längeren Code geschrieben, aber es funktioniert jetzt gut. Danke für die Lösung :) –

0

Hier ist, was ich kam mit. Die Liste der Dateien kann nicht abgerufen werden (mit der Methode listFiles()), da ich viele Dateien habe.

public String[] getFilesList(File path){ 
     String[] filesList = null; 
     final List<String> directories = new ArrayList<String>(); 
     try { 
      properties.load(new StoricoPV_ISAU().getFile()); 
     } catch (IOException e) { 
      log.error(e.getMessage()); 
      e.printStackTrace(); 
     } 
     filesList = path.list(new FilenameFilter() { 
      public boolean accept(File dir, String name) { 
       if(name.matches(Constants.INTERNA_REGEX)){ 
        return true; 
       }else if(name.matches(Constants.SISS_REGEX)){ 
        return true; 
       }else if(new File(properties.getProperty(Constants.PATH_NAME)+name).isDirectory()){ 
        directories.add(properties.getProperty(Constants.PATH_NAME)+name); 
        return false; 
       } 
       return false; 
      } 
     }); 
     String[] tempList = null; 
     for(String directory :directories){ 
      tempList = new File(directory).list(new FilenameFilter() { 
      public boolean accept(File dir, String name) { 
       if(name.matches(Constants.INTERNA_REGEX)){ 
        return true; 
       }else if(name.matches(Constants.SISS_REGEX)){ 
        return true; 
       }else if(new File(properties.getProperty(Constants.PATH_NAME)+name).isDirectory()){ 
        log.info("Invalid file or directory name"); 
        return false; 
       } 
       return false; 
      } 
     }); 
      filesList = (String[])ArrayUtils.addAll(filesList, tempList); 
     } 

     return filesList; 
    } 
Verwandte Themen