Самый быстрый способ найти fileName из шаблона в nio или файловый объект в java - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть место, где я хранил 1 миллион файлов.Я хочу получить все файлы в списке и найти все файлы, которые содержат слово в имени файла из этого списка.Здесь важно только то, что производительность должна быть очень хорошей.Все должно происходить очень быстро, поэтому я ищу самый быстрый способ для этого.Я запутался, следует ли использовать объект файла Java-традиции или NIO.Я пробовал объект файла следующим образом:

    String[] fileList = null;
    String fileNamePart = "somepartoffileName";
      try{
        File rootFolder = new File(dir);
        if(rootFolder.isDirectory()){
            fileList = rootFolder.list();

       }
        catch(Exception e){
        System.out.println("Not a valid directory "+dir);
    }

    String[] listFiles = Arrays.stream(fileList).filter(s -> 
    s.contains(FileNamePart)).toArray(String []::new);

Есть ли более быстрый способ добиться этого?Я не против использовать массив файлов или что-то из nio, но моя производительность должна быть выше.Также сопоставляемому шаблону может быть от 1 до 1000. поэтому может быть одна строка для сопоставления или эта строка может содержать 1000 значений, разделенных запятыми

Ответы [ 3 ]

0 голосов
/ 13 февраля 2019

Вы должны использовать кредит FileVisitor с NIO2 .У Oracle есть подробный пример обхода дерева файлов в различных случаях:

import static java.nio.file.FileVisitResult.*;

// The file we are looking for.
Path lookingFor = ...;

public FileVisitResult
    visitFile(Path file,
        BasicFileAttributes attr) {
    if (file.getFileName().equals(lookingFor)) {
        System.out.println("Located file: " + file);
        return TERMINATE;
    }
    return CONTINUE;
}

Для этого вам не нужно хранить весь список в памяти.

0 голосов
/ 13 февраля 2019

Ваш код излишне сложен, даже по стандартам до Java 8.В спецификации API не упоминаются какие-либо исключения, выдаваемые для недопустимых каталогов (вместо этого метод возвращает null), поэтому нет причин добавлять эту обработку исключений.Кроме того, метод вернет null, если файл не является каталогом, поэтому тест rootFolder.isDirectory() также устарел.

Таким образом, получение нефильтрованного списка так же просто, как

File rootFolder = new File(dir);
String[] fileList = rootFolder.list();

и легко добавить фильтр, теперь вызывая File.list(FilenameFilter), используя функции Java 8:

File rootFolder = new File(dir);
String[] fileList = rootFolder.list((p, n) -> n.contains(fileNamePart));
0 голосов
/ 13 февраля 2019

Лучше не создавать список всех файлов.Традиционно можно использовать FileNameFilter, но с новыми потоками:

Path path = Paths.get(dir);
String[] listFiles = Files.list(path)
    .map(p -> p.getFileName().toString())
    .filter(s -> s.contains(FileNamePart)).toArray(String []::new);

Список выглядит более универсальным:

List<String> listFiles = Files.list(path)
    .map(p -> p.getFileName().toString())
    .filter(s -> s.contains(FileNamePart))
    .collect(Collectors.toList());

Благодаря @jaspreet упоминание поддиректорий нежелательно (у меня было .walk вместо .list).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...