Есть ли в Java 7 с новыми 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. Преобразуйте массив в arrayylist. Затем отсортируйте их, используя метод статической сортировки в классе 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 обеспечивает низкоуровневый доступ к спискам каталогов, но никакой обработки не выполняется, и ее оставляют на усмотрение вызывающей стороны. Новый 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
}
Эти зависимости необходимы для MinMaxPriorityQueue и FileComparator Guava:
<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)