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

Примечание : я также подсчитываю общее количество файлов txt в каталоге.

Это мой код

int count = 0;

private boolean containsTXT(File file) {
        boolean result = false;
        String fList[] = file.list();

        if (fList == null)
            return false;
        else {
            for (int i = 0; i < fList.length; i++) {
                File file = new File(file, fList[i]);
                if (file.isFile() && (file.getName().endsWith("txt"))) {
                    result = true;
                    count++;   // This counts total txt files in the dir
                } else if (file.isDirectory()) {
                    result = containsTXT(file);
                }
            }
        }
        return result;
    }

Я в основном придерживаюсь наиболее общего подхода, но есть приложения, которые выполняют ту же работу, что и я, и работают быстрее. Кто-нибудь знает лучший подход или алгоритм для этой задачи? Благодаря !!

2
varunkr 28 Апр 2016 в 19:40

4 ответа

Лучший ответ

Вы можете использовать библиотеку apache commons io. В частности, FileUtils.listFiles

Collection<File> allTxtFiles = FileUtils.listFiles(folder, new String[]{"txt"}, true)
int count = allTxtFiles.size();

Не уверен, что это будет быстрее, но, как правило, рекомендуется использовать очень популярные библиотеки с открытым исходным кодом вместо того, чтобы изобретать колесо, потому что:

  1. не стоит тратить время на разработку существующего функционала,
  2. в них, скорее всего, нет ошибок, потому что они использовались многими людьми в течение длительного времени,
  3. они были проверены множеством опытных программистов и, скорее всего, очень эффективны и используют быстрые алгоритмы и тому подобное,
  4. Они более удобны для чтения другими разработчиками и вами позже.

Просто попробуйте и посмотрите, сработает ли он для вас.

2
Yashash Gaurav 26 Дек 2016 в 11:53

Вы можете сделать его итеративным, а не рекурсивным, поместив файлы, обнаруженные во время обхода, в список типа FIFO.

Добавить в конец списка все файлы в текущем просматриваемом каталоге. Удалите из головы файл, по которому в данный момент просматривается.

private boolean containsTXT(File rootPath) {
    boolean result = false;

    LinkedList<File> fileFIFO = new LinkedList<>();

    fileFIFO.add(rootPath); //Add root path to the fifo list

    //Traverse the FIFO linkedlist until it's empty
    while(!fileFIFO.isEmpty()){
        File file = fileFIFO.poll(); //Retrieve item from the head

        System.out.println(file.getAbsolutePath()+"\n");

        if(file.isDirectory()){ //If retrieved item from fifo list is a directory
            File[] filesInDir = file.listFiles();

            if(filesInDir != null){
                fileFIFO.addAll(Arrays.asList(file.listFiles())); //Add all files in directory to fifo
            }
        }else if(file.isFile() && (file.getName().endsWith("txt"))){
            result = true;
            break;
        }
    }

    System.out.println("ContainsTXT: "+result);
    return result;
}

Причина использования списка типа FIFO заключается в том, что переход в подкаталоги упорядочен так, как мы хотим.

0
Siddharth 28 Апр 2016 в 17:13

Вы можете использовать FileUtils из Apache Commons I / O для рекурсивного поиска в каталогах и получения имен файлов, оканчивающихся на .txt. В этом комментарии приводится пример.

Рекурсивный список всех файлов из каталога с помощью Java

1
Community 23 Май 2017 в 12:09

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

private boolean containsTXT(File file) {
    String fList[] = file.list();

    if (fList == null)
        return false;
    for (int i = 0; i < fList.length; i++) {
        File file = new File(file, fList[i]);
        if (file.isFile() && (file.getName().endsWith("txt")))
            return true;
        if (file.isDirectory() && containsTXT(file))
            return true;
    }
    return false;
}
1
Brent Washburne 28 Апр 2016 в 17:01