2014-02-12 33 views
3

我試圖探討newDirectoryStream一個DirecoryStream.Filter例如,我可以實現列出目錄下的所有文件(及其所有子目錄)是舊的作爲一個例子,超過60天。DirectoryStream.Filter例如,基於特定的日期/時間

DirectoryStream<Path> dirS = Files.newDirectoryStream(Paths.get("C:/myRootDirectory"), <DirectoryStream.filter>); 

for (Path entry: dirS) 
    { 
     System.out.println(entry.toString()); 
    } 

在上面的代碼中,應該是什麼DirectoryStream.filter?這將是一個很大的幫助,因爲我在一個項目中嘗試刪除比特定時間戳更早的文件,並且pre-java 1.7 File.listFiles()只是掛起。

可以walkFileTree()提供一個選項?

回答

6

如果我得到這個權利,你有2種情況:

  1. 創建自定義filter選擇文件超過60天
  2. 遍歷子目錄(整個FileTree),並收集信息

自定義過濾器更容易實現,使用Calendar類實現60天的條件:

DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() { 
    @Override 
    public boolean accept(Path entry) throws IOException {BasicFileAttributes attr = Files.readAttributes(entry,BasicFileAttributes.class); 
    FileTime creationTime = attr.creationTime(); 
    Calendar cal = Calendar.getInstance(); 
    int days = cal.fieldDifference(new Date(creationTime.toMillis()),Calendar.DAY_OF_YEAR); 
     return (Math.abs(days) > 60); 
     } 
    }; 

正常執行只會查找根目錄中的文件。要查找子目錄,您使用walkFileTree()的猜測是正確的。

但是,這需要實現FileVisitor接口,這是一個簡單的實現,它很幸運地與7 - SimpleFileVisitor捆綁在一起。

要通過遍歷子目錄,您可以選擇覆蓋目錄中的特定方法 - 我已經使用的SimpleFileVisitor這裏preVisitDirectory

Files.walkFileTree(dirs, new SimpleFileVisitor<Path>() { 
      @Override 
      public FileVisitResult preVisitDirectory(Path file, 
        BasicFileAttributes attrs) { 

由於preVisitDirectory會習慣return FileVisitResult.CONTINUE;的情況下,讓你不必任何額外的限制,我們將利用preVisitDirectory方法在應用過濾器的同時迭代我們的目錄1。

Files.walkFileTree(dirs, new SimpleFileVisitor<Path>() { 
      @Override 
      public FileVisitResult preVisitDirectory(Path file, 
        BasicFileAttributes attrs) { 

       DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() { 
        @Override 
        public boolean accept(Path entry) throws IOException { 
         BasicFileAttributes attr = Files.readAttributes(entry, 
           BasicFileAttributes.class); 
         FileTime creationTime = attr.creationTime(); 
         Calendar cal = Calendar.getInstance(); 
         int days = cal.fieldDifference(
           new Date(creationTime.toMillis()), 
           Calendar.DAY_OF_YEAR); 
         return (Math.abs(days) > 60); 
        } 
       }; 
       try (DirectoryStream<Path> stream = Files.newDirectoryStream(
         file, filter)) { 
        for (Path path : stream) { 
         System.out.println(path.toString()); 
        } 
       } catch (IOException ex) { 
        ex.printStackTrace(); 
       } 
       return FileVisitResult.CONTINUE; 

      } 
     }); 

這將使你的文件從整個目錄和子目錄結構爲所需的過濾標準,完成以下主要方法:

public static void main(String[] args) throws IOException { 
     Path dirs = Paths.get("C:/"); 

     Files.walkFileTree(dirs, new SimpleFileVisitor<Path>() { 
      @Override 
      public FileVisitResult preVisitDirectory(Path file, 
        BasicFileAttributes attrs) { 

       DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() { 
        @Override 
        public boolean accept(Path entry) throws IOException { 
         BasicFileAttributes attr = Files.readAttributes(entry, 
           BasicFileAttributes.class); 
         FileTime creationTime = attr.creationTime(); 
         Calendar cal = Calendar.getInstance(); 
         int days = cal.fieldDifference(
           new Date(creationTime.toMillis()), 
           Calendar.DAY_OF_YEAR); 
         return (Math.abs(days) > 60); 
        } 
       }; 
       try (DirectoryStream<Path> stream = Files.newDirectoryStream(
         file, filter)) { 
        for (Path path : stream) { 
         System.out.println(path.toString()); 
        } 
       } catch (IOException ex) { 
        ex.printStackTrace(); 
       } 
       return FileVisitResult.CONTINUE; 

      } 
     }); 

    } 
+0

感謝這些細節。 – Ashley

+0

@Ashley當然,不客氣 – PopoFibo

3

只需創建一個新的DirectoryStream.Filter實例,如果給定的Path對象大於60天,則返回true

DirectoryStream<Path> dirStream = Files.newDirectoryStream(Paths.get("/some/path"), new Filter<Path>() { 
    @Override 
    public boolean accept(Path entry) throws IOException { 
     FileTime fileTime = Files.getLastModifiedTime(entry); 
     long millis = fileTime.to(TimeUnit.MILLISECONDS); 
     Calendar today = Calendar.getInstance(); 
     // L is necessary for the result to correctly be calculated as a long 
     return today.getTimeInMillis() > millis + (60L * 24 * 60 * 60 * 1000); 
    } 
}); 

請注意,這將只給你指定的目錄Path,即根目錄中的文件。 Path參數傳遞給newDirectoryStream(..)

如果你想要子目錄中的所有文件,Files.walkFileTree(..)可能更易於使用。您只需實施FileVisitor即可使用與上述Filter相同的邏輯,存儲您沿途收集的ListSet或對象。