Використання File.listFiles з FileNameExtensionFilter


84

Я хотів би отримати список файлів із певним розширенням у каталозі. В API (Java 6) я бачу метод, File.listFiles(FileFilter)який би це зробив.

Оскільки мені потрібне конкретне розширення, я створив файл FileNameExtensionFilter. Однак я отримую помилку компіляції, коли використовую listFilesз цим. Я припускав, що з тих пір FileNameExtensionFilter implements FileFilterя маю змогу це зробити. Код наступний:

FileNameExtensionFilter filter = new FileNameExtensionFilter("text only","txt");
String dir  = "/users/blah/dirname";
File f[] = (new File(dir)).listFiles(filter);

Останній рядок показує помилку компіляції:

метод listFiles (FileNameFilter) у типі File не застосовується для аргументів типу FileNameExtensionFilter

Я намагаюся використовувати listFiles(FileFilter), ні listFiles(FileNameFilter). Чому компілятор цього не розпізнає?

Це працює, якщо я пишу власний розширений фільтр розширення FileFilter. Я волів би скористатися, FileNameExtensionFilterніж написати своє. Що я роблю не так?


По-перше, вам потрібно мати "txt" як перший аргумент, а "лише текст" як другий.
омар1234

Код правильний, @ lobster1234. Див .: docs.oracle.com/javase/7/docs/api/javax/swing/filechooser/…
james.garriss

Відповіді:


184

FileNameExtensionFilterКлас призначений для свінгу , щоб використовувати вJFileChooser .

Спробуйте використовувати FilenameFilterзамість цього. Наприклад:

File dir = new File("/users/blah/dirname");
File[] files = dir.listFiles(new FilenameFilter() {
    public boolean accept(File dir, String name) {
        return name.toLowerCase().endsWith(".txt");
    }
});

38

Однорядковий в синтаксисі Java 8:

pdfTestDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".txt"));

7
Ви можете пропустити фігурні дужки і повернутися:pdfTestDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".txt"));
Габор Шарняс

Інше рішення:Files.list(Paths.get("your/path")).filter(path -> path.toString().endsWith(".txt")).collect(Collectors.toList());
CeePlusPlus

28

Чи є конкретна причина, яку ви хочете використати FileNameExtensionFilter? Я знаю, що це працює ..

private File[] getNewTextFiles() {
    return dir.listFiles(new FilenameFilter() {
        @Override
        public boolean accept(File dir, String name) {
            return name.toLowerCase().endsWith(".txt");
        }
    });
}

1

Дух .... listFiles вимагає java.io.FileFilter. FileNameExtensionFilter розширює javax.swing.filechooser.FileFilter. Я вирішив свою проблему, реалізувавши екземпляр java.io.FileFilter

Редагувати: я використав щось подібне до відповіді @ cFreiner. Я намагався використовувати метод Java API замість того, щоб писати власну реалізацію, саме тому я намагався використовувати FileNameExtensionFilter. У моїй програмі є багато FileChoosers і я використовував FileNameExtensionFilters для цього, і я помилково припустив, що він також розширює java.io.FileFilter.


1

Ось щось, що я швидко зробив, і воно повинно працювати набагато краще, ніж File.getName (). EndWith (". Xxxx");

import java.io.File;
import java.io.FileFilter;

public class ExtensionsFilter implements FileFilter 
{
    private char[][] extensions;

    private ExtensionsFilter(String[] extensions)
    {
        int length = extensions.length;
        this.extensions = new char[length][];
        for (String s : extensions)
        {
            this.extensions[--length] = s.toCharArray();
        }
    }

    @Override
    public boolean accept(File file)
    {
        char[] path = file.getPath().toCharArray();
        for (char[] extension : extensions)
        {
            if (extension.length > path.length)
            {
                continue;
            }
            int pStart = path.length - 1;
            int eStart = extension.length - 1;
            boolean success = true;
            for (int i = 0; i <= eStart; i++)
            {
                if ((path[pStart - i] | 0x20) != (extension[eStart - i] | 0x20))
                {
                    success = false;
                    break;
                }
            }
            if (success)
                return true;
        }
        return false;
    }
}

Ось приклад для різних форматів зображень.

private static final ExtensionsFilter IMAGE_FILTER = 
      new ExtensionsFilter(new String[] {".png", ".jpg", ".bmp"});

10
Добре, але моя нова мантра полягає в тому, щоб робити речі простими, якщо вони не потребують ускладнення, тобто використанням методів / класів Java API, якщо мені не потрібно писати власні.
Ану

@JeremyTrifilo Чому ти зробив шлях [pStart - i] | 0x20 в коді?
Sohil

1
Навіщо винаходити колесо?
james.garriss

| 20 стосувався варіацій верхнього та нижнього регістру. Це сила додає 32 до листа, що робить його малою буквою для перевірки. Таким чином, ви можете зберегти файл як Example.PnG або Example.pNg, і він все одно буде його вибирати. Зазвичай я не переробляю подібні речі, але роблю це, бо це чудове навчання, якщо ти можеш зрозуміти, як ці речі працюють і що можна зробити, щоб зробити їх кращими. Однак я розумію, що ви маєте на увазі, що для цього сценарію це зайве, оскільки підвищення продуктивності мінімальне, і це не вимагає швидкості.
Jeremy Trifilo

1

За допомогою лямбда-файлів Java (доступних з Java 8) ви можете просто перетворити javax.swing.filechooser.FileFilterїх java.io.FileFilterв один рядок.

javax.swing.filechooser.FileFilter swingFilter = new FileNameExtensionFilter("jpeg files", "jpeg");
java.io.FileFilter ioFilter = file -> swingFilter.accept(file);
new File("myDirectory").listFiles(ioFilter);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.