序言
需要读取sftp服务器上符合指定的文件名正则的文件列表,目前想到的最好的办法就是递归。
我这里引入的依赖是:
<!-- jsch-sftp连接 -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
不废话直接上代码:
public static List<String> getFileList(ChannelSftp channelSftp, String path, String fileNamePattern, Integer filePathDepth) {
List<String> fileList = Lists.newLinkedList();
try {
Pattern pattern = Pattern.compile(fileNamePattern);
Vector<ChannelSftp.LsEntry> files = channelSftp.ls(path);
//读取的根路径下一级就是文件
if (1 == filePathDepth) {
for (ChannelSftp.LsEntry entry : files) {
String fileName = entry.getFilename();
//找到和规则(文件名正则)匹配的文件
if (pattern.matcher(fileName).matches()) {
//拼接全路径
String fullPath = path + fileName;
fileList.add(fullPath);
}
}
} else {
//从读取根路径下开始算目录深度时,目录深度大于1就使用递归来读取文件列表
manyDirFileList(channelSftp, path, fileNamePattern, fileList, bComFilesaveReadruleDO.getDirPattern());
}
} catch (Exception e) {
log.error("获取sftp指定目录下的文件列表失败,{}", e.getMessage());
}
return fileList;
}
/**
* 递归获取提供的路径下多级目录下符合正则的所有文件
*
* @param channelSftp ftp对象
* @param path 路径
* @param fileList 文件列表
**/
public static void manyDirFileList(ChannelSftp channelSftp, String path, String fileNamePattern,
List<String> fileList, String dirPattern) throws Exception {
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 l : vector) {
ChannelSftp.LsEntry file = (ChannelSftp.LsEntry) l;
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() ? "/" : "");
manyDirFileList(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());
throw new Exception("递归获取SFTP指定目录下的文件列表失败,路径:" + path + ",异常信息:" + e.getMessage());
}
}
另外还有一个需求就是只读取10个文件:
public static List<String> getFileListFor10(ChannelSftp channelSftp, String path, String fileNamePattern, Integer filePathDepth) {
List<String> fileList = Lists.newLinkedList();
try {
Pattern pattern = Pattern.compile(fileNamePattern);
Vector<ChannelSftp.LsEntry> files = channelSftp.ls(path);
//读取的根路径下一级就是文件
if (1 == filePathDepth) {
for (ChannelSftp.LsEntry entry : files) {
if (fileList.size() > 10) {
log.info("已读取10个文件,不再读取目录:{}下的文件", path);
break;
}
String fileName = entry.getFilename();
//找到和规则(文件名正则)匹配的文件
if (pattern.matcher(fileName).matches()) {
//拼接全路径
String fullPath = path + fileName;
fileList.add(fullPath);
}
}
} else {
//从输入的根路径下开始算目录深度时,目录深度大于1就使用递归来读取文件列表
manyDirFileListFor10(channelSftp, path, fileNamePattern, fileList, bComFilesaveReadruleDO.getDirPattern());
}
} catch (Exception e) {
log.error("获取sftp指定目录下的文件列表失败,{}", e.getMessage());
}
return fileList;
}
/**
* 递归获取提供的路径下多级目录下符合正则的前10个文件
*
* @param channelSftp ftp对象
* @param path 路径
* @param fileList 文件列表
**/
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());
}
}
-----------------知道的越多, 不知道的越多--------------------