我有一个如下所示的文件夹存档:
C:\Users\myUser\myArchive\.
├───v1.ci
│ └───Linux
│ ├───111-001
│ └───222-ci
├───v1.dev
│ └───Linux
│ ├───111-001
│ ├───222-001
│ └───333-001
├───v2.ci
│ └───Linux
│ ├───111-001
│ └───222-ci
├───v2.dev
│ └───Linux
│ ├───111-001
│ ├───222-001
│ └───333-001
└───v2.safe
└───Linux
├───111-001
└───222-ci
我想在Java中创建一个静态函数,给定一个存档路径(在本示例中为位置C:\Users\myUser\myArchive\
)和一个模式,该函数返回一个List<String>
且所有与该模式匹配的文件夹。
例如,如果我说setupsArchive
= C:\Users\myUser\myArchive\
和pattern
= v*.ci
,则该列表应由v1.ci
和{{ 1}}(与该模式匹配的两个文件夹)。
注意:无需递归。我只关心存档下面的文件夹名称,而不关心其中的内容。
此函数在Unix环境中运行时有效:
v2.ci
但是,当我在Windows上运行它时,它将在此行上引发异常:
private static List<String> getVersionsMatchingPattern(String pattern, String setupsArchive) {
File allVersions = new File(setupsArchive);
FileFilter versionFilter = pathname -> pathname.isDirectory() && pathname.toString().matches(setupsArchive + pattern);
File[] filteredVersions = allVersions.listFiles(versionFilter);
List<String> matchedVersions = new ArrayList<>();
for (File version : filteredVersions) {
matchedVersions.add(version.getName());
}
matchedVersions.sort(Collections.reverseOrder());
return matchedVersions;
}
该异常是FileFilter versionFilter = pathname -> pathname.isDirectory() && pathname.toString().matches(setupsArchive + pattern);
,它的发生是因为(与Unix不同,在Windows中,路径分隔符是反斜杠java.util.regex.PatternSyntaxException: Illegal/unsupported escape sequence near index 3
,当我发送\
时,{{1} }被解释为Regex,在C:\Users\...
部分中是非法的。
我了解到,我需要转义正则表达式的\u
部分,并仅将pathname.toString().matches(setupsArchive + pattern)
与模式部分一起使用。
因此,我尝试:
setupsArchive
match()
在这两种情况下,代码都能正常编译和执行,但不会过滤任何内容(即,即使存在与模式匹配的数据,列表也将返回空)。
有人知道吗?
答案 0 :(得分:1)
您可以利用Pattern#asPredicate()
作为名称的过滤器。
File#getName()
将返回目录名称(不包含完整路径)。
您可以按类型(dir / file)过滤文件,然后再次过滤结果,也可以将文件转换为名称然后过滤。
final Pattern rx = Pattern.compile("AB"); // Matches names wich contain 'AB'
File baseDir = new File("C:\\Users\\myUser\\myArchive\\");
Predicate<String> nameMatcher = rx.asPredicate();
// this will result in a list of File
List<File> result = Arrays.stream(baseDir.listFiles())
.filter(f->f.isDirectory())
.filter(f->nameMatcher.test(f.getName()))
.collect(Collectors.toList());
System.out.println(result); // [C:\Users\myUser\myArchive\ABC003PR, C:\Users\myUser\myArchive\TAB113]
// this will result in a list of String
List<String> result2 = Arrays.stream(baseDir.listFiles())
.filter(f->f.isDirectory())
.map(File::getName)
.filter(nameMatcher)
.collect(Collectors.toList());
System.out.println(result2); // [ABC003PR, TAB113]