【问题标题】:How to exclude a specific file with Apache FileFilterUtils?如何使用 Apache FileFilterUtils 排除特定文件?
【发布时间】:2014-11-11 13:13:34
【问题描述】:

请考虑以下文件夹结构:

src
  |_text1.txt
  |_text2.txt
  |_content
      |_text1.txt
      |_text2.txt

我如何设计一个 org.apache.commons.io.filefilter.IOFileFilter 来排除 src/text1.txtsrc/text2 .txt 但保留 src/content/text1.txtsrc/content/text2.txt ?

目前我的过滤器如下所示:

IOFileFilter filter = FileFilterUtils.and(
                    FileFilterUtils.notFileFilter(FileFilterUtils.nameFileFilter("text1.txt", IOCase.SENSITIVE)),
                    FileFilterUtils.notFileFilter(FileFilterUtils.nameFileFilter("text2.txt", IOCase.SENSITIVE))
            );
FileUtils.copyDirectory(new File("src"), new File("dst"), filter);

但是上面的代码 sn-p 显然也没有复制 src/content/ 文件夹中的两个文本文件(我想复制)...顺便说一句。文本文件的名称不可更改。

有什么想法吗?

【问题讨论】:

    标签: java apache file filter copy


    【解决方案1】:

    AFAIK commons io 不提供类似PathFileFilter 的内容,因此您必须在此处添加自己的过滤器。

    NameFileFilter,顾名思义,只检查文件名,即路径不相关。

    提供您自己的过滤器应该不会那么难。我建议在这里继承AbstractFileFilterNameFileFilter。子类化 NameFileFilter 可能被认为是一种有点脏的方法,因为您不仅要检查名称,而且只需要覆盖 accept() 方法:

    public boolean accept(File file) {
       return accept( file.getPath() );
    }
    
    public boolean accept(File dir, String name) {
      //use normalize to account for possible double separators or windows paths which use \
      return accept( FilenameUtils.normalize( dir.getPath() + "/" + name ) );
    }
    
    protected boolean accept( String path ) {     
       for (String nameSuffix: names) {
         if (caseSensitivity.checkEndsWith( path, nameSuffix )) {
             return true;
         }
       }
       return false;
    }
    

    然后你会像FileFilterUtils.notFileFilter(new PathFileFilter("/text1.txt")) 等一样使用它。

    或者,您可以提供一组模式并检查它们:

    private Set<Pattern> pathPatterns = new HashSet<>();
    
    PathFileFilter(String... patterns) {
       for( String p : patterns ) {
         pathPatterns.add( Pattern.compile(p) );
       }
    }
    
    protected boolean accept( String path ) {     
      for (Pattern pattern : pathPatterns) {
        //separatorsToUnix is used to convert \ to /
        if ( pattern.matches( FilenameUtils.separatorsToUnix( path ) )) {
          return true;
        }
      }
      return false;
    }
    

    用法:new PathFileFilter("(?i)(.*/)?test[12]\\.txt");new PathFileFilter("(?i)(.*/)?test1\\.txt", "(?i)(.*/)?anothertest2\\.txt");

    正则表达式的简短分解:

    • (?i) 使表达式不区分大小写,不区分大小写匹配
    • (.*/)? 表示如果文件名前面有任何内容,则它必须以斜杠结尾,即这将匹配 some/path/test1.txt 但不匹配 someothertest1.txt
    • test[12]\\.txt 是文件名,这里的意思是text,后跟12,最后是.txt

    【讨论】:

      猜你喜欢
      • 2016-05-28
      • 2023-03-26
      • 2019-01-06
      • 2022-12-14
      • 1970-01-01
      • 2018-01-23
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多