В Java 7 с новыми API-интерфейсами ввода-вывода есть ли простой способ перечислить содержимое каталога по дате последнего изменения? В основном мне нужно только получить файл, который не был изменен в течение самого долгого времени (сортировка по последнему измененному возрастанию, первое имя файла).
Получить файлы в каталоге, отсортированном по последнему измененному?
Ответ 1
Там нет реального "простого способа", но это возможно:
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
не перебирать подкаталоги.
Ответ 2
Небольшое "потоковое" изменение ответа Джеффри, которое, возможно, также станет легче. Публикация для полноты.
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 -> {
});
}
Ответ 3
Используйте listFiles() в каталоге File object. Преобразуйте массив в arraylist. Затем отсортируйте их с помощью метода статической сортировки в классе Collections с помощью специального Comparator, который использует метод getTotalSpace() в файлах. EDIT: используйте lastModified вместо getTotalSpace.
Ответ 4
lastModified()
Возвращает время последнего изменения файла, обозначенного этим абстрактным именем пути.
Ответ 5
вы можете использовать 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)
Ответ 6
Примечание. Для этого решения требуется Guava.
API Java IO/NIO обеспечивает низкоуровневый доступ к спискам каталогов, но обработка не выполняется, что остается для вызывающего. Новый 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>
Вы также можете найти параметр фильтр параметра 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)