文件名过滤器的使用

Posted

技术标签:

【中文标题】文件名过滤器的使用【英文标题】:Use of FilenameFilter 【发布时间】:2013-11-24 19:48:34 【问题描述】:

我有一个目录:

File dir = new File(MY_PATH);

我想列出名称以整数字符串表示的所有文件,例如“10”、“20”。 我知道我应该使用:

dir.list(FilenameFilter filter);

如何定义我的FilenameFilter

P.S. 我的意思是文件名可以是任何整数字符串,例如“10”或“2000000”或“3452345”。只要文件名是整数字符串,位数没有限制。

【问题讨论】:

我以前从来没有这样做过,但是 10 秒在谷歌上说你应该做new FileNameFilter() 然后实现一个匿名内部类来选择你应该接受的文件名。 【参考方案1】:

您应该在界面覆盖 accept FilenameFilter 并确保参数name 仅包含数字字符。您可以使用matches 进行检查:

String[] list = dir.list(new FilenameFilter() 
    @Override
    public boolean accept(File dir, String name) 
        return name.matches("[0-9]+");
    
);

【讨论】:

@OldCurmudgeon 除非你不能(例如,前缀作为输入参数) 是否可以将 hte 数组类型更改为 File[] 而不是 String[]?【参考方案2】:

最好作为匿名内部类的实例作为参数传递给File#list。

例如,仅列出以扩展名 .txt 结尾的文件:

File dir = new File("/home");
String[] list = dir.list(new FilenameFilter() 
    @Override
    public boolean accept(File dir, String name) 
        return name.toLowerCase().endsWith(".txt");
    
);

要仅列出文件名正好是 2 位整数的文件,您可以在 accept 方法中使用以下内容:

return name.matches("\\d2");

一位或多位数字:

return name.matches("\\d+");    

编辑(作为对@crashprophet 评论的回应)

将一组文件的扩展名传递给列表

class ExtensionAwareFilenameFilter implements FilenameFilter 

    private final Set<String> extensions;

    public ExtensionAwareFilenameFilter(String... extensions) 
        this.extensions = extensions == null ? 
            Collections.emptySet() : 
                Arrays.stream(extensions)
                    .map(e -> e.toLowerCase()).collect(Collectors.toSet());
    

    @Override
    public boolean accept(File dir, String name) 
        return extensions.isEmpty() || 
            extensions.contains(getFileExtension(name));
    

    private String getFileExtension(String filename) 
        String ext = null;
        int i = filename .lastIndexOf('.');
        if(i != -1 && i < filename .length()) 
            ext = filename.substring(i+1).toLowerCase();
        
        return ext;
    



@Test
public void filefilter() 
    Arrays.stream(new File("D:\\downloads").
        list(new ExtensionAwareFilenameFilter("pdf", "txt")))
            .forEach(e -> System.out.println(e));

【讨论】:

我需要过滤掉文件以仅获取名称包含整数作为字符串的文件,没有扩展名。例如。 “10”、“20” 如何参数化 endsWith(parameter) 调用?如果我想在某些情况下搜索 .txt 或 .pdf,我该怎么做? @crashprophet 通过创建一个自己的实现FilenameFilter 的类并将您想要过滤的扩展传递给它。 File#list 方法的参数不再是匿名类,而是您创建的新类的实例。请参阅代码示例。 感谢 A4L,我最终做了类似以下的事情:private final String filter; public FilterAwareFilenameFilter(String filter) this.filter = filter; @Override public boolean accept(File dir, String name) return filter.toLowerCase().endsWith(this.filter); // 我不知道我之前在做什么,但在你的例子之后它现在可以工作了!【参考方案3】:

从 Java 8 开始,您可以简单地使用 lambda 表达式来指定您的自定义过滤器:

dir.list((dir1, name) -> name.equals("foo"));

在上面的示例中,只有名称为“foo”的文件才能通过。当然用你自己的逻辑。

【讨论】:

这里如何指定模式而不是equal()方法? @gaurav 只需像这样使用matches 方法:dir.list((dir1, name) -&gt; name.matches("[0-9]+"));【参考方案4】:

我这样做:

    File folder = new File(".");
    File[] listOfFiles = folder.listFiles();
    for (File file : listOfFiles) 
        if (file.isFile()) 
            if (file.toString().endsWith(".sql")) 
                System.out.println(file.getName());
            
        
    
    System.out.println("End!!");

【讨论】:

优秀的解决方案但是您应该将 .toLowerCase() 添加到最后一个“if”语句中。【参考方案5】:

这就是我的结局。它使用了一个很好的 lambda 表达式,可以很容易地扭曲到您自己的设计中......

File folder = new File(FullPath);
String[] files = folder.list((lamFolder, lamName) -> lamName.matches("[0-9]+"));
if(files == null) 
    System.out.println("Stuff wrongly: no matching files found.");
 else 
    for(String file : files) 
        System.out.println("HOORAY: I found this "+ file);
    

【讨论】:

以上是关于文件名过滤器的使用的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 juce 的 FileFilter 描述我想要的文件过滤器?

QFileSystemModel - 检测空文件夹(使用“AllDirs”过滤器)?

Django——模板路径 模板变量 常用过滤器 静态文件的使用

当我在 multer 中使用文件过滤器时如何捕捉错误?

GetOpenFileName 可以将文件选择限制为与过滤器匹配的文件吗?

45文件过滤器FilenameFilter