将 File.listFiles 与 FileNameExtensionFilter 一起使用
Posted
技术标签:
【中文标题】将 File.listFiles 与 FileNameExtensionFilter 一起使用【英文标题】:Using File.listFiles with FileNameExtensionFilter 【发布时间】:2011-08-10 17:10:16 【问题描述】:我想获取目录中具有特定扩展名的文件列表。在 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);
最后一行显示编译错误:
File 类型的方法 listFiles(FileNameFilter) 不适用于 FileNameExtensionFilter 类型的参数
我正在尝试使用listFiles(FileFilter)
,而不是listFiles(FileNameFilter)
。为什么编译器不能识别这个?
如果我编写自己的扩展过滤器扩展 FileFilter
,这将有效。我宁愿使用FileNameExtensionFilter
而不是自己写。我做错了什么?
【问题讨论】:
首先,您需要将“txt”作为第一个参数,将“仅文本”作为第二个参数。 代码正确,@lobster1234。见:docs.oracle.com/javase/7/docs/api/javax/swing/filechooser/… 【参考方案1】: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");
);
【讨论】:
【参考方案2】:java 8 语法中的单行:
pdfTestDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".txt"));
【讨论】:
可以省略花括号并返回:pdfTestDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".txt"));
另一种解决方案:Files.list(Paths.get("your/path")).filter(path -> path.toString().endsWith(".txt")).collect(Collectors.toList());
【参考方案3】:
您是否有特定原因要使用FileNameExtensionFilter
?我知道这行得通..
private File[] getNewTextFiles()
return dir.listFiles(new FilenameFilter()
@Override
public boolean accept(File dir, String name)
return name.toLowerCase().endsWith(".txt");
);
【讨论】:
【参考方案4】:使用 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.FileFilter
和 io.FileFilter
但只想定义一次,这将特别有用。【参考方案5】:
Duh.... listFiles 需要 java.io.FileFilter。 FileNameExtensionFilter 扩展 javax.swing.filechooser.FileFilter。我通过实现 java.io.FileFilter 的实例解决了我的问题
编辑:我确实使用了类似于@cFreiner 的答案。我试图使用 Java API 方法而不是编写自己的实现,这就是我尝试使用 FileNameExtensionFilter 的原因。我的应用程序中有很多 FileChoosers,并为此使用了 FileNameExtensionFilters,我错误地认为它也在扩展 java.io.FileFilter。
【讨论】:
【参考方案6】:这是我快速制作的东西,它的性能应该比 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");
【讨论】:
好,但我的新口号是保持简单,除非它们需要更复杂,也就是说,除非我真的必须自己编写,否则使用 Java API 方法/类。 @JeremyTrifilo 你为什么做了 path[pStart - i] | 0x20 在代码中? 为什么要重新发明***? 该 | 20 用于大写与小写的变体。它强制将 32 添加到字母,使其成为小写字母以进行检查。因此,您可以将文件另存为 Example.PnG 或 Example.pNg,它仍然会拾取它。我通常不会重做这样的事情,但我这样做是因为如果你能理解这些事情是如何工作的,以及可以做些什么来让它们变得更好,那将是很好的学习。但是我明白你的意思,因为性能提升很小,所以对于这种情况来说它是多余的,并且不需要快速。以上是关于将 File.listFiles 与 FileNameExtensionFilter 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
File.listFiles() 使用 JDK 6 破坏 unicode 名称(Unicode 规范化问题)
如何在 Java 7 中用 nio 替换 File.listFiles(FileFilter filter)?