Самый быстрый способ перечислить файлы в Java - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть десятки или даже сотни тысяч файлов для списка. Я подумал, что это будет довольно просто: например, запуск find -iname "*.abc" | wc -l выполняется на моем ноутбуке Ubuntu. К сожалению, эквивалентный код в Java, основанный на старом добром File File, довольно медленный.

Причина, по-видимому, заключается в том, что каждый экземпляр File содержит много метаданных, в то время как команда find достаточно умна, чтобы игнорировать все, что не является строго необходимым в ее поиске.

Кажется, что в NIO 2 есть несколько "новых" конструкций, которые делают нашу жизнь лучше: у нас есть новый API на основе Visitor и API DirectoryStream. Но они все еще как-то отстают по сравнению с find.

Какой самый быстрый из самых быстрых подходов в Java, когда все, что нам нужно, это перечислить (или, скажем, чтобы упростить на данный момент, подсчитать) огромное количество файлов в наборе папок?

Спасибо

1 Ответ

0 голосов
/ 05 сентября 2018

Возможно, вы могли бы попробовать вызывать команды оболочки, используя ProcessBuilder. Приведенный ниже код показывает, как выполнить команду поиска из Java.

public static void main(final String[] args) throws IOException {
    // if running linux:
    runFind();
}

private static void runFind() throws IOException {
    String[] commandList = {"/bin/sh", "-c", "find -iname \"*.txt\" | wc -l"};
    ProcessBuilder processBuilder = new ProcessBuilder(commandList);
    processBuilder.redirectOutput(Redirect.INHERIT); // Redirect output of process
    Process process = processBuilder.start();
}

Код выше будет работать только на устройствах Unix. Единственным отличием для Windows будет ваш список команд:

String[] commandList = { "cmd.exe", "/C", "dir" };

Замените "dir" на то, что эквивалентно тому, что вы делаете в Windows.

Если вы хотите, чтобы ваша программа была совместима с различными операционными системами, вы можете создать ветку на основе ОС для обработки либо команды windows, либо команды unix, а затем использовать метод, который вы в настоящее время используете для File, если можете ' t по какой-то причине запустите процесс, как указано выше.

Если вы используете этот метод, вам придется перенаправить вывод процесса на то, что вы можете манипулировать в Java.

...