Подтвердить что ты не робот

Могу ли я проверить размер коллекции, поскольку она заселена

Я перечисляю файлы в файловой системе Java, используя следующий класс Apache Commons:

Collection<File> allFiles = FileUtils.listFiles(rootDirectory, null, recursive);

Это очень длинный процесс и может занять до 5 минут.

Есть ли способ проверить размер коллекции во время ее заполнения?

Я попытался получить доступ к нему из отдельного потока, но просто получил нуль, пока процесс не был готов.

4b9b3361

Ответ 1

Вы можете использовать FileUtils IOFileFilter.

Collection<File> listFiles = FileUtils.listFiles(new File("."), counter, FileFilterUtils.trueFileFilter());

где счетчик будет вдоль строк

IOFileFilter counter = new IOFileFilter() {

    @Override
    public boolean accept(File arg0, String arg1) {
        countCall();
        return true;
    }

    @Override
    public boolean accept(File arg0) {
        countCall();
        return true;
    }
};

и countCall - это метод, который обновляет ход выполнения.

Ответ 2

Пока вы не получите возвращаемое значение из метода, вы не сможете получить доступ к коллекции по мере ее заполнения, потому что у вас нет доступа к переменной, которую этот метод использует внутри.

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

Лучшей альтернативой, если вы используете Java 7, является использование интерфейса FileVisitor для изучения файловой системы. Он имеет несколько методов обратного вызова, которые позволяют отслеживать прогресс.

Ответ 3

Я думаю, вы можете попробовать использовать исполняемые команды, такие как перенаправление списка команд в файл temp и чтение его с помощью Java File API.

ls > temp.txt

Я создал простую оболочку script, которая будет перечислять файлы в указанном индексе.

#!/bin/bash

RANGE_UP=$2
RANGE_BOT=$1

CURRENT_CNTR=0

FILENAME=._m_ls

ls -w 1 > $FILENAME
while read line
do
    if [ $CURRENT_CNTR -le $RANGE_UP -a $CURRENT_CNTR -gt $RANGE_BOT ]; then
    printf $line"\n"
    fi
    CURRENT_CNTR=`expr $CURRENT_CNTR + 1`
done < $FILENAME

Теперь вы можете сделать что-то вроде ./ls_range.sh 10000 30000 >temp.txt, а затем прочитать из этого файла, используя BufferedReader в другом потоке.

Ответ 4

Ваш единственный способ сделать это (в отличие от java7 или расщепления работы, как было предложено ранее) - это написать собственный код для поиска через файловую систему при обновлении обратного вызова.

Я использовал код из commons-io и модифицировал его в соответствии с вашими потребностями, очевидно, он нуждается в тестировании, но он подсчитывает файлы по мере их нахождения.

Пример

interface Counter {
    void foundFile(File file);
}

final class FileSearcher {
    public static Collection<File> listFiles(File root, FileFilter filter, Counter counter) {
        Collection<File> files = new ArrayList<File>();
        File[] found = root.listFiles(filter);

        if (found != null) {
            for (int i = 0; i < found.length; i++) {
                if (found[i].isDirectory()) {
                    files.addAll(listFiles(found[i], filter, counter));
                } else {
                    files.add(found[i]);
                    counter.foundFile(found[i]);
                }
            }
        }

        return files;
    }
}

И затем используйте его следующим образом:

final AtomicInteger inte = new AtomicInteger(0);
FileSearcher.listFiles(new File("C:/"), null, new Counter() {
    @Override
    public void foundFile(File file) {
        System.out.println("found file number " + inte.addAndGet(1));
    }
});