В Java 7 с новите I/O API, има ли лесен начин за изброяване на съдържанието на директория по дата на последна промяна? По принцип трябва само да получа файла, който не е бил модифициран най-дълго време (сортирай по последна промяна във възходящ ред, вземете първото име на файл).
Получаване на файлове в директория, сортирани по последна промяна?
Отговори (6)
Няма истински „лесен начин“ да го направите, но е възможно:
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 не преминават през поддиректории.
TreeSet
, тази грешка може да направи .add()
неуспешна.
- person daveloyall; 03.04.2015
Малко по-скоростна вариация на отговора на Джефри, която някои може да намерят и по-лесна. Публикуване за пълнота.
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 -> {
});
}
sorted
е преди filter
?
- person Mark Jeronimus; 28.11.2020
Използвайте listFiles() върху обекта File на директорията. Преобразувайте масива в списък с масиви. След това ги сортирайте, като използвате статичния метод за сортиране в класа Collections с персонализиран Comparator, който използва метода getTotalSpace() във Files. РЕДАКТИРАНЕ: Използвайте lastModified вместо getTotalSpace.
lastModified()
Връща времето, когато файлът, означен с този абстрактен път, е бил последно модифициран.
File f = new File(""); Arrays.sort(f.listFiles(), new Comparator<File>() { public int compare(File o1, File o2) { return (int)(o1.lastModified() - o2.lastModified()); } }); return f[0];
- person atomman; 04.09.2012
можете да използвате http://docs.oracle.com/javase/1.5.0/docs/api/java/io/File.html#listFiles(java.io.FileFilter) и предоставяне на http://docs.oracle.com/javase/1.5.0/docs/api/java/io/FileFilter.html
след това сравнете http://docs.oracle.com/javase/1.5.0/docs/api/java/io/File.html#lastModified() и сте готови
ако ви е грижа за производителността - тогава просто вземете такъв с максимална/минимална стойност от списъка с файлове, което ще ви даде O(n) сложност
Забележка: Това решение изисква Guava.
Java IO/NIO API осигурява достъп на ниско ниво до списъци с директории, но няма извършена обработка, което е оставено на повикващия. Новият Java7 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
}
Тези зависимости са необходими за Guava MinMaxPriorityQueue и FileComparator:
<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>
Може също да намерите полезен параметъра filter на 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)