将File.listFiles与FileNameExtensionFilter一起使用


82

我想在目录中获取具有特定扩展名的文件列表。在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)。为何编译器无法识别这一点?

如果我编写自己的扩展过滤器extend,则此方法有效FileFilter。我宁愿用而不愿FileNameExtensionFilter自己写。我究竟做错了什么?


首先,您需要将“ txt”作为第一个参数,将“仅文本”作为第二个参数。
lobster1234 2011年

该代码是正确的@ lobster1234。请参阅:docs.oracle.com/javase/7/docs/api/javax/swing/filechooser/...
james.garriss

Answers:



37

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

28

您要使用某个特定原因FileNameExtensionFilter吗?我知道这有用。

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

1

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

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


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

10
很好,但是我的新口头禅是使事情保持简单,除非它们需要更复杂,即使用Java API方法/类,除非我真的必须编写自己的方法。
阿努

@JeremyTrifilo为什么要完成路径[pStart-i] | 代码中的0x20?
索希尔(Sohil)2016年

1
为什么要重新发明轮子?
james.garriss

| 20是大写和小写的变体。强制在字母上加上32,使其成为小写字母以进行检查。因此,您可以将文件另存为Example.PnG或Example.pNg,它仍会选择它。我通常不会重做这样的事情,但是我这样做是因为,如果您能理解这些事情的工作原理以及如何使它们变得更好,那是非常好的学习。但是,我得到您的意思是,对于这种情况而言,这是多余的,因为性能提升很小,并且不需要很快。
杰里米·特里菲洛

1

使用Java lambdas(从Java 8开始可用),您只需将其转换javax.swing.filechooser.FileFilterjava.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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.