Как пройти по дереву каталогов огромного каталога и игнорировать файлы
Мне нужно пройти каталог на сетевом диске и создать карту дочернего к родительскому в иерархии. Один репрезентативный каталог составляет 6 террабайт, имеет 900 000 файлов и 900 папок. Я забочусь только о папках, а не о файлах. В целях тестирования я скопировал папки без файлов на другой сетевой диск и запустил свой код на скопированной версии. Простое перебор 900 папок занимает, возможно, 10 секунд. Однако перебор исходной структуры каталогов занимает 30 минут. Похоже, что мы перебираем все 900 000 файлов, хотя мы просто игнорируем их.
Есть ли способ ускорить это, даже не глядя на файлы? Я бы предпочел придерживаться чистой Java, если мы можем. При просмотре этого огромного каталога через Windows Explorer, он не чувствует себя медленно. Мой код ниже.
public static Map<String, String> findFolderPaths(File parentFolder) throws IOException {
Map<String, String> parentFolderMap = new HashMap<String, String>();
Files.walkFileTree(parentFolder.toPath(), new FolderMappingFileVisitor(parentFolderMap));
return parentFolderMap;
}
static class FolderMappingFileVisitor extends SimpleFileVisitor<Path> {
private Map<String, String> mapping;
FolderMappingFileVisitor(Map<String, String> map) {
this.mapping = map;
}
@Override
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes attrs) throws IOException {
File directory = dir.toFile();
mapping.put(directory.getName(), directory.getParent());
return FileVisitResult.CONTINUE;
}
}
Редактировать:
Важная часть загадки, которую я не упомянул, состоит в том, что мы запускаем приложение в веб-старте. Время, о котором я сообщал, было от производства, а не от разработки. Работая с Eclipse, время больше, чем я ожидаю от FileWalker.
2 ответа
Обходчик файлов работает намного быстрее, чем File.listFiles(). Кажется, проблема в Java Webstart. Когда я запускаю приложение в рабочей среде под Java Webstart, это занимает около 30 минут. Когда я запускаю приложение из Eclipse, это занимает пару минут. Java Webstart просто убивает нас с точки зрения производительности.
Это приложение очень интенсивно использует данные /io, и в прошлом я замечал другие проблемы с этим приложением при работе в Webstart. Решение состоит в том, чтобы перейти от Java Webstart.
Метод, который вы используете, заключается в получении BasicFileAttributes, который, я подозреваю, посещает информацию описания файла каждого файла.
Если вам нужны только имена, я предлагаю вам повторно / рекурсивно вызывать File.listFiles(); и это должно только получить информацию, которую вы запрашиваете.
Что-то вроде
public static Map<String, String> findFolderPaths(File parentFolder) throws IOException {
Map<String, String> map = new HashMap<String, String>();
findFolderPaths(parentFolder, map);
return map;
}
public static void findFolderPaths(File dir, Map<String, String> map) throws IOException {
map.put(dir.getName(), dir.getPparent());
for(File file : dir.listFiles())
if (file.isDirectory())
findFolderPaths(file, map);
}
Как видите, это не то, что вам не нужно.