请考虑以下文件夹结构:
src
|_text1.txt
|_text2.txt
|_content
|_text1.txt
|_text2.txt
如何设计 org.apache.commons.io.filefilter.IOFileFilter 以排除 src / text1.txt 和 src / text2 .txt 但保留 src / content / text1.txt 和 src / 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);
但上面的代码片段显然不会复制 src / content / 文件夹中的两个文本文件(我想复制它)...顺便说一句。 不可更改文本文件的名称。
有什么想法吗?
答案 0 :(得分:1)
AFAIK commons io没有提供像PathFileFilter
这样的东西,因此你必须在这里添加你自己的过滤器。
NameFileFilter
,顾名思义,只检查文件名,即路径不相关。
提供自己的过滤器不应该那么难。我建议在此处对AbstractFileFilter
或NameFileFilter
进行子类化。子类化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
,后跟1
或2
,最后为.txt