java 递归读取前10个匹配的文件所在的全路径
需求
有个需求:在连接ftp成功后,读取指定目录下匹配正则表达式的前10个文件。很显然这个需要使用递归,因为会有不同层级的文件目录,不能写死来处理。
第一版代码展示
public static void test(ChannelSftp channelSftp, String path, String fileNamePattern,List<String> fileList, String dirPattern) {
// 如果已经找到了10个文件,直接返回,不再递归
if (fileList.size() >= 10) {
log.info("已读取10个文件,不再读取目录:{}下的文件", path);
return;
}
try {
List<Pattern> dirPatterns = new ArrayList<>();
if (StringUtils.isNotEmpty(dirPattern)) {
for (String pat : dirPattern.split(",")) {
dirPatterns.add(Pattern.compile(pat.trim()));
}
}
Pattern fileNamePat = Pattern.compile(fileNamePattern);
if (isDirectory(channelSftp, path)) {
Vector<?> vector = channelSftp.ls(path);
for (Object o : vector) {
ChannelSftp.LsEntry file = (ChannelSftp.LsEntry) o;
String fileName = file.getFilename();
boolean isDirMatch = dirPatterns.isEmpty();
for (Pattern dirPat : dirPatterns) {
if (dirPat.matcher(fileName).matches()) {
isDirMatch = true;
break;
}
}
if (fileName.equals(".") || fileName.equals("..")) {
continue;
}
if (isDirMatch || fileNamePat.matcher(fileName).matches()) {
String fullPath = path + fileName + (file.getAttrs().isDir() ? "/" : "");
manyDirFileListFor10(channelSftp, fullPath, fileNamePattern, fileList, dirPattern);
}
}
} else {
String fileName = path.substring(path.lastIndexOf("/") + 1);
if (fileNamePat.matcher(fileName).matches()) {
fileList.add(path);
}
}
} catch (SftpException e) {
log.error("获取FTP指定目录下的文件异常,路径:{},异常信息:{}", path, e.getMessage());
} catch (Exception e) {
log.error("递归获取SFTP指定目录下的文件列表失败,路径:{},异常信息:{}", path, e.getMessage());
}
}
当fileList有10个元素了之后,走到return之后并没有结束,而是会继续往下走递归,于是有了第二版:
public static void manyDirFileListFor10(ChannelSftp channelSftp, String path, String fileNamePattern,
List<String> fileList, String dirPattern) {
try {
List<Pattern> dirPatterns = new ArrayList<>();
if (StringUtils.isNotEmpty(dirPattern)) {
for (String pat : dirPattern.split(",")) {
dirPatterns.add(Pattern.compile(pat.trim()));
}
}
Pattern fileNamePat = Pattern.compile(fileNamePattern);
if (isDirectory(channelSftp, path)) {
Vector<?> vector = channelSftp.ls(path);
for (Object o : vector) {
// 如果已经找到了10个文件,直接返回,不再递归
if (fileList.size() >= 10) {
log.info("已读取10个文件,不再读取目录:{}下的文件", path);
break;
}
ChannelSftp.LsEntry file = (ChannelSftp.LsEntry) o;
String fileName = file.getFilename();
boolean isDirMatch = dirPatterns.isEmpty();
for (Pattern dirPat : dirPatterns) {
if (dirPat.matcher(fileName).matches()) {
isDirMatch = true;
break;
}
}
if (fileName.equals(".") || fileName.equals("..")) {
continue;
}
if (isDirMatch || fileNamePat.matcher(fileName).matches()) {
String fullPath = path + fileName + (file.getAttrs().isDir() ? "/" : "");
manyDirFileListFor10(channelSftp, fullPath, fileNamePattern, fileList, dirPattern);
}
}
} else {
String fileName = path.substring(path.lastIndexOf("/") + 1);
if (fileNamePat.matcher(fileName).matches()) {
fileList.add(path);
}
}
} catch (SftpException e) {
log.error("获取FTP指定目录下的文件异常,路径:{},异常信息:{}", path, e.getMessage());
} catch (Exception e) {
log.error("递归获取SFTP指定目录下的文件列表失败,路径:{},异常信息:{}", path, e.getMessage());
}
}
这里将fileList.size()>=10的判断放在for循环里,这样就可以了。
----------------------------知道的越多,不知道的越多-------------------------