在 FileNameExtensionFilter 中使用 File.listFiles

我想得到一个目录中具有特定扩展名的文件列表。在 API (Java6)中,我看到一个方法 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);

最后一行显示一个编译错误:

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

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

如果我编写自己的扩展过滤器扩展 FileFilter,就可以做到这一点。我宁愿使用 FileNameExtensionFilter而不是编写我自己的。我做错了什么?

212995 次浏览

The FileNameExtensionFilter class is intended for Swing to be used in a JFileChooser.

Try using a FilenameFilter instead. For example:

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");
}
});

Is there a specific reason you want to use FileNameExtensionFilter? I know this works..

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

Duh.... listFiles requires java.io.FileFilter. FileNameExtensionFilter extends javax.swing.filechooser.FileFilter. I solved my problem by implementing an instance of java.io.FileFilter

Edit: I did use something similar to @cFreiner's answer. I was trying to use a Java API method instead of writing my own implementation which is why I was trying to use FileNameExtensionFilter. I have many FileChoosers in my application and have used FileNameExtensionFilters for that and I mistakenly assumed that it was also extending java.io.FileFilter.

Here's something I quickly just made and it should perform far better than 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;
}
}

Here's an example for various images formats.

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

One-liner in java 8 syntax:

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

With java lambdas (available since java 8) you can simply convert javax.swing.filechooser.FileFilter to java.io.FileFilter in one line.

javax.swing.filechooser.FileFilter swingFilter = new FileNameExtensionFilter("jpeg files", "jpeg");
java.io.FileFilter ioFilter = file -> swingFilter.accept(file);
new File("myDirectory").listFiles(ioFilter);