使用 FileNameExtensionFilter 和 File.listFiles

94

我想获取一个目录下特定扩展名的文件列表。在API(Java 6)中,我看到了一个方法File.listFiles(FileFilter) 可以实现这一功能。

由于我需要特定的扩展名,所以我创建了一个FileNameExtensionFilter。然而当我使用listFiles方法时,出现了编译错误。我以为由于FileNameExtensionFilter实现了FileFilter接口,我应该能够做到这一点。以下是代码:

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

最后一行显示编译错误:

类型为File的方法listFiles(FileNameFilter)不适用于FileNameExtensionFilter类型的参数

我尝试使用listFiles(FileFilter),而不是listFiles(FileNameFilter)。为什么编译器不能识别?

如果我编写自己的扩展过滤器并将其扩展为FileFilter,则此方法有效。但我宁愿使用FileNameExtensionFilter而不是编写自己的过滤器。我做错了什么?


首先,您需要将“txt”作为第一个参数,将“仅文本”作为第二个参数。 - lobster1234
代码是正确的,@lobster1234。请参见:http://docs.oracle.com/javase/7/docs/api/javax/swing/filechooser/FileNameExtensionFilter.html - james.garriss
6个回答

195

这个FileNameExtensionFilter类是为了在Swing中使用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");
    }
});

53

Java 8语法中的一行代码:

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

7
你可以省略花括号并返回:pdfTestDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".txt")); - Gabor Szarnyas
另一种解决方案:Files.list(Paths.get("your/path")).filter(path -> path.toString().endsWith(".txt")).collect(Collectors.toList()); - CeePlusPlus

31

你想使用 FileNameExtensionFilter 有特定的原因吗?我知道这个可以起作用。

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

2

使用Java Lambdas(自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);

谢谢,如果您需要同时使用 filechooser.FileFilterio.FileFilter,但只想定义一次,这将非常有用。 - j-hap

1

这是我刚刚做的东西,它应该比File.getName().endsWith(".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"});

11
很不错,但我的新口头禅是除非必须更加复杂,否则保持简单,也就是说,尽量使用Java API方法/类,除非我确实需要编写自己的方法。 - Anu
@JeremyTrifilo,为什么在代码中做了path[pStart - i] | 0x20? - Sohil
1
为什么要重复造轮子呢? - james.garriss
20是用于大写和小写变化的。它强制将字母加上32,使其成为小写字母进行检查。因此,您可以将文件保存为Example.PnG或Example.pNg,它仍然可以被识别。我通常不会重新做这样的事情,但我这样做是因为如果您能理解这些东西的工作原理以及如何改进它们,那么这将是很好的学习机会。但是我明白您的意思,对于这种情况来说,这是多余的,因为性能提高很小,也没有必要让它快速运行。 - Jeremy Trifilo

0

咦……listFiles需要java.io.FileFilter。FileNameExtensionFilter扩展了javax.swing.filechooser.FileFilter。我通过实现java.io.FileFilter的一个实例来解决了我的问题。

编辑:我确实使用了类似@cFreiner答案的东西。我试图使用Java API方法而不是编写自己的实现,这就是为什么我尝试使用FileNameExtensionFilter的原因。我在我的应用程序中有许多FileChoosers,并为此使用了FileNameExtensionFilters,并错误地认为它也扩展了java.io.FileFilter。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接