2012-09-03 82 views

回答

16

有沒有真正的「簡單的方式」來做到這一點,但它是可能的:

List<Path> files = new ArrayList<>(); 
try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) { 
    for(Path p : stream) { 
     files.add(p); 
    } 
} 

Collections.sort(files, new Comparator<Path>() { 
    public int compare(Path o1, Path o2) { 
     try { 
      return Files.getLastModifiedTime(o1).compareTo(Files.getLastModifiedTime(o2)); 
     } catch (IOException e) { 
      // handle exception 
     } 
    } 
}); 

這將盡快修改過的文件最後文件進行排序。 DirectoryStream s不會遍歷子目錄。

+0

感謝您提供完整的解決方案。 File.listFiles()可能使你的代碼更短:-) –

+1

@ stefan.at.wpf但它不會使用NIO2根據您的請求 – Jeffrey

+0

啊好吧,對不起,沒有注意到。我不需要NIO,我只是想知道NIO是否會提供簡單的解決方案;-) –

0
lastModified() 

返回上次修改此抽象路徑名錶示的文件的時間。

Java 7 - IO API

+0

謝謝你,而是出於與像100個文件的目錄,我需要得到最古老的一個,只是想知道,如果有比手動比較所有上次更改時間值,例如更好的辦法僅傳遞一個排序選項,然後根據排序方向獲取列表的第一個或最後一個條目。 –

+0

爲了知道哪個文件是最新的/最舊的,有必要遍歷所有文件。這是(我的知識)FileFilter所做的。除了在jdevelop的文章(編輯:可能有很多方法來實現這個)中提到的唯一的東西,就是創建一個比較器作爲這個'File f = new File(「」); Arrays.sort(f.listFiles(),新的比較(){ 公衆詮釋比較(文件O1,O2文件){ 回報(INT)(o1.lastModified() - o2.lastModified()); } }); 返回f [0];' – atomman

2

在目錄的File對象上使用listFiles()。將數組轉換爲數組列表。然後使用在文件上使用getTotalSpace()方法的自定義比較器對Collections類使用靜態排序方法對它們進行排序。 編輯:使用lastModified而不是getTotalSpace。

0

注意:此解決方案需要番石榴。

Java IO/NIO API提供低級訪問到目錄列表,但沒有處理完成,這是留給調用者的。 新的J ava7 NIO DirectoryStream在訪問目錄列表以供進一步處理時具有最小的佔用空間,例如,排序。

這裏是我的解決:從DirectoryStream閱讀文件,並建立一個有序隊列(可選)從流規模有限。從隊列中返回最舊/最新的元素。

private void listFilesOldestFirst(final File directory, final Integer maxNumberOfFiles) { 

    final Builder<File> builder = 
      MinMaxPriorityQueue 
      .orderedBy(LastModifiedFileComparator.LASTMODIFIED_COMPARATOR); 
    if(maxNumberOfFiles != null) { 
     builder.maximumSize(maxNumberOfFiles); 
    } 

    // queue with constant space, if maxNumberOfFiles is set, otherwise behaves like an unbound queue with an O(log n) penalty for insertion 
    final MinMaxPriorityQueue<File> oldestFiles = builder.create(); 

    try(DirectoryStream<Path> stream = Files.newDirectoryStream(directory.toPath())) { 
     for(final Path p : stream) { 
      oldestFiles.add(p.toFile()); 
     } 
    } catch (final IOException e) { 
     throw new RuntimeException(e); 
    } 

    final File[] fileArray = oldestFiles.toArray(new File[]{}); 
    Arrays.sort(fileArray, oldestFiles.comparator()); 
    // ... use fileArray 

    final ArrayList<File> arrayList = Lists.newArrayList(oldestFiles); 
    Collections.sort(arrayList, oldestFiles.comparator()); 
    // ... use arrayList 

} 

這些依賴所需番石榴MinMaxPriorityQueueFileComparator

<dependency> 
     <groupId>com.google.guava</groupId> 
     <artifactId>guava</artifactId> 
     <version>18.0</version> 
    </dependency> 
    <dependency> 
     <groupId>commons-io</groupId> 
     <artifactId>commons-io</artifactId> 
     <version>2.4</version> 
    </dependency> 

您也可以找到過濾參數Files.newDirectoryStream有用:

final Filter<Path> sampleFilter = new Filter<Path>() { 
     @Override 
     public boolean accept(final Path entry) throws IOException { 
      return true; // see commons-io -> FileFilterUtils 
     } 
    }; 

    ... 
    Files.newDirectoryStream(directory.toPath(), sampleFilter) 
4

傑弗裏答案稍微「流」的變化,有些人可能會發現更容易。過帳完整性。

try (DirectoryStream<Path> files = Files.newDirectoryStream(path)) { 
    StreamSupport.stream(files.spliterator(), false) 
     .sorted((o1, o2) -> { 
      try { 
       return Files.getLastModifiedTime(o1).compareTo(Files.getLastModifiedTime(o2)); 
      } catch (IOException ex) { 
       ... 
      } 
     }) 
     .filter(file -> Files.isRegularFile(file)) 
     .forEach(file -> { 
     }); 
} 
相關問題