2016-01-09 186 views
3

我需要在文件列表上應用更復雜的邏輯。具體而言,應用軟件更新的時候,我想從更新的zip壓縮文件獲取的文件進行操作如下:爲目錄和子目錄中的每個文件執行一些操作

  • updateFile從更新歸檔文件,originalFile當前版本的文件和backupFile原始文件
  • 的備份
  • originalFile如果是相同的當前運行jar文件,跳過它
  • 如果updateFile的父目錄是特定的名稱,跳過它(例如,與用戶數據目錄)

我寧願像跑步回調每個文件的一些選項:

GreatFileLibrary.forEveryChildOf(new File("my path"), 
           (File child)->{ ... logic here ... }); 

如果不是這樣的話,至少只是通過它得到一些Collection和循環中的所有文件:

Iterable<File> files = GreatFileLibrary.listChildren(new File("my path")); 
for(File child:files) { 
    ... logic ... 
} 

的前者可以讓我顯示進度(感謝列表長度),但我坦率地認爲更新幾乎是即時的。

當然文件可以返回一些兒童名單,所以尤伯杯幼稚的做法是:

/** Returns list of all child files, recursively. **/ 
    public static Iterable<File> listFileChildren(File parent, ArrayList<File> list) { 
    File[] files = parent.listFiles(); 
    for(File file:files) { 
     list.add(file); 
     if(file.isDirectory()) 
     listFileChildren(file, list); 
    } 
    return list; 
    } 
    public static Iterable<File> listFileChildren(File parent) { 
    return listFileChildren(parent, new ArrayList()); 
    } 

燦內置Java 8庫做的更好?我的快速代碼是否有缺陷?我會真的欣賞刪除將File[]轉換爲Iterable<File>作爲我的代碼,這很髒。

+0

我不知道的東西,你想怎麼複雜,做每一個文件,但是這看起來像是從shell腳本來完成,使用'find' –

+0

@ WalterTross雖然在這一刻我作出僅適用於Windows程序,我更喜歡使用跨平臺代碼儘可能。而我從命令行運行的一些函數(獲取UUID進行加密)實際上是有問題的... –

+0

我看到了 - 無論如何,Cygwin是你的朋友 –

回答

2

在你的代碼列表創建將是最耗時,因此請儘量避免使用它。 一個這樣做將是簡單的方法:

public void forEveryChildOf(File file) { 
    for(File child:file.listFiles()) 
     doForEach(file,child); 
} 

private void doForEach(File topParent,File child){ 
    if(child.isFile()) 
     System.out.println("Do logic"); 

    if(child.isDirectory()) 
     for(File subchild:child.listFiles()) 
      doForEach(topParent,subchild); 
} 
-1

可以按如下方式處理文件:

public void forEachChild(File parent, Consumer<File> yourLogic){ 
    for(File f : parent.listFiles()) 
     yourLogic.accept(f); 
} 
+0

遞歸的地方在哪裏?我有文件夾'圖像'和其中的子文件夾。這些也將得到更新,需要檢查。這也是因爲我只備份即將被替換的文件以節省空間...... –

+0

您寫道:「我寧願有一些選項爲每個文件運行回調。所以這是選項。 –

+0

我做到了。我還在標題中寫了**和子目錄** ......混淆的地方是什麼? –

0
public void allFiles(File raiz) {   
    for (File arquivo : raiz.listFiles(filtro)) { 
     if (arquivo.isFile()) { 
      try {    
      System.out.println(arquivo); 
      } catch (Exception e) { 
      System.out.println("erro" +arquivo); 
      } 
     } else { 
     allFiles(arquivo); 
     } 
    } 
} 
1

如果你不介意創建多個數據流的性能影響,此函數將返回到你每一個孩子的流中的目標文件夾。

下面的版本採用Java 7FilesPath類的,所以你可能需要重寫一些事情(或者叫Path#toFile

public static Stream<Path> stream(Path path) { 
    try { 
     return Files.isDirectory(path) ? Files.list(path).map(innerpath -> stream(innerpath)).flatMap(s -> s) : Stream.of(path); 
    } catch (IOException e) { 
     throw new RuntimeException(e); 
    } 
} 

這個版本使用普通的舊File小號

public static Stream<File> stream(File file) { 
    return file.isDirectory() ? Arrays.stream(file.listFiles()).map(innerfile -> stream(innerfile)).flatMap(s -> s) : Stream.of(file); 
} 

您可以在最終Stream上收集List或致電forEach

0

FileVisitor從NIO:

Path startPath = new File("...").toPath(); 
    Files.walkFileTree(startPath, new SimpleFileVisitor<Path>() { 
     @Override 
     public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 
       throws IOException { 
      //your logic 

      return FileVisitResult.CONTINUE; 
     } 
    }); 
相關問題