Чтение имен файлов частями в потоках Java из папки - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть каталог с миллионами файлов.Я хочу прочитать имена файлов в ArrayList.Если я прочитал все имена файлов в ArrayList, он потребляет больше памяти.Я подозреваю, что если в каталоге присутствует огромное количество файлов, Java может выдать ошибку пространства кучи.Есть ли способ читать файлы в каталоге в чанках / пакетах, каждый раз произнося 5 имен файлов.

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Вы можете использовать Path.list для этого, он вернет вам поток, который оценивается лениво:

List<String> fileNames = Path.list("path_to_directory")
                             .map(Path::getFileName)
                             .collect(Collectors.toList());

Файлы будут обработаны один за другим, и это будетпотреблять меньше памяти.Однако у вас все еще могут возникнуть проблемы с памятью, если окончательный список fileNames станет слишком большим.Таким образом, операция терминала (сбора) в поточном конвейере может вызвать некоторые проблемы.

Но, например, если вы обрабатываете имя файла непосредственно в потоке (используя forEach, например, не собирая их), вы можете избежать загрузки всех имен в память.

Path.list("path_to_directory")
    .map(Path::getFileName)
    .forEach(System.out::println); 

// printфайлы по одному, не загружая их все одновременно.

Надеюсь, это поможет.

0 голосов
/ 27 ноября 2018

Вы можете использовать FileVisitor класс для обхода и чтения по одному файлу за раз.Таким образом, вы не получите ошибку OOM.

Используйте Files.html # walkFileTree метод для посещения файлов в каталоге.

Общий пример приведен ниже.

Path path = FileSystems.getDefault().getPath("D:\\path\\with\\lots\\of\\files");
        Files.walkFileTree(path, new FileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                return FileVisitResult.CONTINUE;
            }

        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            // here you have the files to process
            System.out.println(file);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
           return FileVisitResult.TERMINATE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
          return FileVisitResult.CONTINUE;
        }
    });

Вот ссылка на Учебник по Java SE .Дополнительные примеры см. Здесь .

...