我有点卡在一个项目上.. 基本上,我得到一个目录来扫描通过某些过滤器的文件。
命令文件包含带过滤的行(给定的过滤器名称存储在枚举文件中)指令。像这样举例如: 后缀%TXT EXEC%YES
如果是这样,它将返回以txt(扩展名)结尾的所有文件并且是可执行的.. 到目前为止没有问题。
问题从这样的行开始: 后缀%txt exec%YES(在同一行)在这种情况下,它应该返回所有以txt或者可执行文件结尾的文件。
我正在使用String.split(“%”)拆分该行并将其放入带有键和值的映射中,而不是遍历每个键并检查枚举中的哪个过滤器,并执行所需的检查
当我每行有超过1个过滤器时,我有点坚持如何识别。 我尝试使用第一个过滤器作为键来执行HashMap,并且值是包含所有其他的列表(使用split(“”)来分解过滤器.. 我不能依赖偶数或奇数索引上的键,因为过滤器可能在其末尾有另一个%NOT(后缀%txt%NOT),它将返回所有不以txt结尾的文件。 ..
任何帮助将不胜感激! 谢谢!
答案 0 :(得分:2)
如何:创建一个Filter
接口,并编写一个函数,根据文件内容将文件解析为单个过滤器。你有类似的东西:
interface Filter {
boolean passesFilter(File file);
}
class SuffixFilter implements Filter {
SuffixFilter(String suffix) { ... }
public boolean passesFilter(File file) {
// return true if file has the appropriate suffix
}
}
class ExecutableFilter implements Filter {
... // filter that returns true if the file is executable
}
// now for the interesting part ...
class NegationFilter implements Filter {
private final Filter subfilter;
NegationFilter(Filter subfilter) {
this.subfilter = subfilter;
}
public boolean passesFilter(File file) {
return !subfilter.passesFilter(file);
}
}
class AndFilter implements Filter {
private final Collection<Filter> subfilters;
AndFilter(Collection<Filter> subfilters) {
this.subfilters = subfilters;
}
public boolean passesFilter(File file) {
for (Filter subfilter : subfilters) {
if (!subfilter.passesFilter(file)) {
return false;
}
}
return true;
}
}
class OrFilter implements Filter {
private final Collection<Filter> subfilters;
OrFilter(Collection<Filter> subfilters) {
this.subfilters = subfilters;
}
public boolean passesFilter(File file) {
for (Filter subfilter : subfilters) {
if (subfilter.passesFilter(file)) {
return true;
}
}
return false;
}
}
有了这个,您只需要构建所有基本过滤器,然后同一行中的相邻元素将OrFilter
编辑在一起,而在单独行上的过滤器(或过滤或未过滤)得到{{ 1}}在一起。这是一个草图:
AndFilter
你在从你的文件中读出的行上调用Filter readAndFilter(Iterable<String> fileLines) {
List<Filter> subfilters = new ArrayList<Filter>();
for (String line : fileLines) {
subfilters.add(readOrFilter(line));
}
return new AndFilter(subfilters);
}
Filter readOrFilter(String fileLine) {
List<Filter> subfilters = new ArrayList<Filter>();
for (String oneFilter : fileLine.split(" ")) {
Filter filter = buildOneFilter(oneFilter);
subfilters.add(filter);
}
return new OrFilter(subfilters);
}
Filter buildOneFilter(String oneFilterClause) {
// parse as you were doing before
}
,你得到的回报总是一个readAndFilter
你可以传递文件,它会告诉你他们是否通过了过滤。 (注意:如果您愿意,可以使用我的Filter
和readAndFilter
方法来检查他们要返回的列表是否长度为1,如果是,则返回一个过滤器而不是一个元素的readOrFilter
或And
。它不会影响正确性,但它可能使调试输出更容易阅读。)