2015-11-26 39 views
1

我希望能夠尋找一個大的目錄,其中包括所謂的「在線」爲文件夾中所有子文件夾,並添加一旦發現列表中的文件夾。搜索多個文件夾大型目錄 - JAVA

換句話說:這個文件是一個文件夾嗎?如果沒有忽略,如果是,這個文件夾稱爲「在線」?,如果是,則添加到列表,如果沒有打開並循環瀏覽文件夾內容並重新開始。

我有一個腳本:

String fileType = "online"; 

private void buildList(File aFile) { 
if (aFile.isDirectory()) { 

    if (fileName.contains(fileType)) { 
     addToList(aFile); 
    } else { 
     for (File bFile : aFile.listFiles()) { 
      buildList(bFile); 
     } 
    } 
} 
} 

這適用於小目錄,罰款,對大的目錄由於大量陣列具有開放。它掛起並耗盡了所有的內存。

我接受所有建議。 JAVA只與JDK1.6兼容。非常感謝您提前!

編輯:

static long counter = 0L; 
ArrayList<File> opFolders; 


public final class DirectoryCollectorVisitor extends SimpleFileVisitor<Path> { 

    private final List<Path> list; 



    public DirectoryCollectorVisitor(final List<Path> list) { 


     this.list = list; 
    } 

    @Override 
    public FileVisitResult preVisitDirectory(final Path path, final BasicFileAttributes attrs) { 
     counterPrintField.setText("" + counter++); 
     if (path.getFileName().toString().contains("online")) { 
      list.add(path); 
      File aFile = path.toFile(); 
      opFolders.add(aFile); 
     } 
     return FileVisitResult.CONTINUE; 
    } 
} 



private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {           

    JFileChooser chooser = jFileChooser1; 
    chooser.setCurrentDirectory(new java.io.File("O:\\Prod\\Clients")); 
    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 
    chooser.setAcceptAllFileFilterUsed(false); 
    int returnVal = chooser.showOpenDialog(this); 

    if (returnVal == chooser.APPROVE_OPTION) { 
     File file = chooser.getSelectedFile(); 
     try { 
      jTextArea1.setText(null); 
      opFolders = new ArrayList<>(); 

      final Path baseDir = Paths.get(file.getAbsolutePath()); 
      final List<Path> dirList = new ArrayList<>(); 
      dirList.add(baseDir); 

      final FileVisitor<Path> visitor = new DirectoryCollectorVisitor(dirList); 
      Files.walkFileTree(baseDir, visitor); 
      if(opFolders.isEmpty()){ 
       System.err.println("EMPTY"); 
      } 
      for (File aFile : opFolders) { 
       if (!aFile.isDirectory() && !aFile.getName().toLowerCase().endsWith(".db")) { 
        jTextArea1.append(aFile.getAbsolutePath() + "\n"); 

       } 

      } 

      jTextArea1.append("...COMPLETE..."); 
     } catch (Exception ex) { 
      System.out.println("Problem accessing directory: " + file.getAbsolutePath()); 
     } 
    } else { 
     System.out.println("File access cancelled by user."); 
    } 

} 

@fge更新的代碼

+1

Java 6的唯一?太糟糕了......如果你使用了Java 7+,那將會是一個解決方案。對於Java 6,你幾乎是SOL(懶洋洋地閱讀目錄條目)。但是,這是2015年,所以強制性問題:爲什麼Java 6?已經到達壽命終點的時間已經過去了 – fge

+0

這真是太棒了。定義'大目錄' –

+0

@UmaKanth根本不奇怪;設想一個目錄層次結構,其中每個級別有數十個甚至數百個數千個文件,並且遞歸地走向它們。作爲File的'.listFiles()'返回一個數組,它別無選擇,只能急於填充數組,這很快就會導致大量的內存消耗。從JSR 203和'DirectoryStream'開始,這不再是一個問題。 – fge

回答

0

不幸的是,你說你被限制到Java 6,鑑於需求沒有辦法用File API來做到這一點。 .listFiles()只能以熱切的方式填充目錄條目。

嘛,會有一個方式......只要你使用一個類似Unix的操作系統,你可以使用一個ProcessBuilder,並用命令如find -type d -name online發出從基本目錄的過程:

final File baseDir = ...; 
final ProcessBuilder pb = new ProcessBuilder(
    "find", "-type", "d", "-name", "online" 
); 
pb.directory(baseDir); 

final Process p = pb.start(); 
// use the Process' InputStream 

如果你使用Java 7+你有一個更容易的時間;編程FileVisitor收集到一個列表:

public final class DirectoryCollectorVisitor 
    extends SimpleFileVisitor<Path> 
{ 
    private final List<Path> list; 

    public DirectoryCollectorVisitor(final List<Path> list) 
    { 
     this.list = list; 
    } 

    @Override 
    public FileVisitResult previsitDirectory(final Path path, final BasicFileAttributes attrs) 
    { 
     if (path.getFileName().toString().equals("online")) 
      list.add(path); 
     return FileVisitResult.CONTINUE; 
    } 
} 

// ... 

final Path baseDir = Paths.get(...); 
final List<Path> dirList = new ArrayList<>(); 
final FileVisitor<Path> visitor = new DirectoryCollectorVisitor(list); 
Files.walkFileTree(baseDir, visitor); 
// dirList is not filled with the entries 

使用Java 8,它更簡單:

private static final BiPredicate<Path, BasicFileAttributes> ONLINE_DIRS 
    = (path, attrs) -> attrs.isDirectory() 
    && path.getFileName().toString().equals("online"); 

// ... 

final Path baseDir = Paths.get(...); 
final List<Path> dirList; 

try (
    final Stream<Path> stream = Files.find(baseDir, Integer.MAX_VALUE, 
     ONLINE_DIRS); 
) { 
    dirList = stream.collect(Collectors.toList()); 
} 
+0

好,所以Java 7解決方案有點工作,但速度很慢。花費1分鐘循環瀏覽500個文件。任何建議,以改善這一點?謝謝!!! – ldhxvs

+0

@ldhxvs是500個文件總數還是500個結果? – fge

+0

共534個文件夾共1個目錄(2,326個文件) – ldhxvs

相關問題