最近做到一个需求,是需要根据日期及文件名称(非必填)从SFTP服务器上读取文件并压缩成ZIP文件给用户下载,简单记录一下实现的思路
1.首先使用账号密码连接到SFTP中
/**
* 登录SFTP
*
* @param userName 用户名
* @param password 密码
* @param host 主机地址
*/
private ChannelSftp loginSftp(String userName, String password, String host, int port) {
JSch jsch = new JSch();
try {
Session sshSession = jsch.getSession(userName, host, port);
sshSession.setPassword(password);
sshSession.setConfig("StrictHostKeyChecking", "no");
sshSession.connect(sftpDownConfig.getSessionConnectTimeout());
Channel channel = sshSession.openChannel("sftp");
channel.connect(sftpDownConfig.getChannelConnectTimeout());
return (ChannelSftp) channel;
} catch (JSchException e) {
log.error("loginSftp error,errorMessage", e);
}
return null;
}
2.根据地址访问目录并打包返回ZIP文件流,由于需求文件名称是非必填,所以需要根据类型判断是日期的话打包目录下所有文件,如果为名称则打包对应名称。
private ZipArchiveOutputStream zipFile(String dir, List<String> files, ChannelSftp channelSftp, ZipArchiveOutputStream zipOut){
for (String fileName : files) {
String filePath = dir + "/" + fileName;
boolean exist = checkFileExist(filePath, channelSftp);
if (!exist) {
log.error("文件 {} 不存在", filePath);
return null;
}
try (InputStream inputStream = channelSftp.get(filePath)) {
if (inputStream != null) {
ZipArchiveEntry entry = new ZipArchiveEntry(fileName);
zipOut.putArchiveEntry(entry);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
zipOut.write(buffer, 0, bytesRead);
}
zipOut.closeArchiveEntry();
} else {
log.error("文件 {} 未找到", filePath);
}
} catch (SftpException | IOException e) {
log.error("处理文件 {} 时出错", filePath, e);
}
}
return zipOut;
}
private boolean returnZip(HttpServletResponse response, String dir, String date, List<String> files, ChannelSftp channelSftp){
try {
// 设置响应头
response.setContentType("application/zip");
String zipFileName = date + "_sftp_files.zip";
response.setHeader("Content-Disposition", "attachment; filename=" + zipFileName);
ServletOutputStream outputStream = response.getOutputStream();
ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(outputStream);
ZipArchiveOutputStream zipArchiveOutputStream = zipFile(dir, files, channelSftp, zipOut);
if (zipArchiveOutputStream == null) {
log.error("文件不存在,压缩失败");
return false;
}
zipOut.finish();
zipOut.close();
outputStream.flush();
outputStream.close();
} catch (IOException e) {
log.error("写入响应流时出错", e);
} finally {
logoutSftp(channelSftp);
}
return true;
}
3.断开SFTP连接
/**
* 关闭SFTP
*/
private void logoutSftp(ChannelSftp channelSftp) {
try {
if (channelSftp == null) {
return;
}
if (channelSftp.isConnected()) {
channelSftp.disconnect();
}
if (channelSftp.getSession() != null) {
channelSftp.getSession().disconnect();
}
} catch (Exception ex) {
log.error("logoutSftp error,errorMessage", ex);
}
}
最后在main方法做好参数的设置及逻辑的判断,调用这些方法就行

590

被折叠的 条评论
为什么被折叠?



