【问题标题】:Using File.listFiles with FileNameExtensionFilter将 File.listFiles 与 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 而不是自己写。我做错了什么?

【问题讨论】:

标签: java file filter java-6


【解决方案1】:

FileNameExtensionFilter 类旨在供 SwingJFileChooser 中使用。

尝试改用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.FileFilterio.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,它仍然会拾取它。我通常不会重做这样的事情,但我这样做是因为如果你能理解这些事情是如何工作的,以及可以做些什么来让它们变得更好,那将是很好的学习。但是我明白你的意思,因为性能提升很小,所以对于这种情况来说它是多余的,并且不需要快速。
        猜你喜欢
        • 2013-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多