项目场景:
场景:有时候我们会遇到需要将sftp上的多个文件压缩成zip再上传到sftp上保存。
相关代码
public void saveZipFile(XXX xxx, List<String> fileUrlList) {
try {
// 其他逻辑
....
InputStream inputStream = compressFiles(fileUrlList);
boolean success = fileSystemService.uploadFile(filePath, inputStream);
if (success) {
// 其他逻辑
.....
}
}
} catch (Exception e) {
log.error("saveZipFile failed, caused by: {}", e.getMessage(), e);
}
}
public InputStream compressFiles(List<String> fileUrlList) throws Exception {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream out = new ZipOutputStream(baos)) {
for (String fileUrl : fileUrlList) {
compressFile(out, fileUrl);
}
// 之前因为没有加这句导致生成的压缩包一直无法打开,找了很久原因才找到
out.finish();
return new ByteArrayInputStream(baos.toByteArray());
}
}
public void compressFile(ZipOutputStream out, String fileUrl) throws Exception {
try (InputStream fileContent = fileSystemService.downloadFileAsInputStream(String.format("%s%s", config.getRoot(), fileUrl))) {
ZipEntry zipEntry = new ZipEntry(fileUrl.substring(fileUrl.lastIndexOf('/') + 1));
out.putNextEntry(zipEntry);
byte[] buffer = new byte[1024];
int length;
while ((length = fileContent.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
out.closeEntry();
}
}
部分内容解释:
fileUrlList:是sftp上的文件地址;
InputStream fileContent = fileSystemService.downloadFileAsInputStream(String.format(“%s%s”, config.getRoot(), fileUrl)):是从sftp上下载并把文件转成输入流;
其余代码如下:
// 下载文件并转成输入流
@Override
public InputStream downloadFileAsInputStream(String targetPath) throws Exception {
ChannelSftp sftp = this.createSftp();
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
sftp.cd(config.getRoot());
log.info("Change path to {}", config.getRoot());
sftp.get(targetPath, byteArrayOutputStream);
InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
log.info("Download file success. TargetPath: {}", targetPath);
return inputStream;
} catch (Exception e) {
log.error("Download file failure. TargetPath: {}", targetPath, e);
throw new ServiceException("Download File failure");
} finally {
this.disconnect(sftp);
}
}
// 上传生成的zip文件
@Override
public boolean uploadFile(String targetPath, InputStream inputStream) throws Exception {
ChannelSftp sftp = this.createSftp();
try {
sftp.cd(config.getRoot());
log.info("Change path to {}", config.getRoot());
int index = targetPath.lastIndexOf("/");
String fileDir = targetPath.substring(0, index);
String fileName = targetPath.substring(index + 1);
boolean dirs = this.createDirs(fileDir, sftp);
if (!dirs) {
log.error("Remote path error. path:{}", targetPath);
throw new Exception("Upload File failure");
}
sftp.put(inputStream, fileName);
return true;
} catch (Exception e) {
log.error("Upload file failure. TargetPath: {}", targetPath, e);
throw new ServiceException("Upload File failure");
} finally {
this.disconnect(sftp);
}
}
总结:
以上就是把sftp的文件下载压缩并上传的大致内容,整体和本地压缩文件差别不大,就是在不熟悉的情况下被压缩文件打不开问题困扰了很久,所以记录一下,希望能给同样碰到这个问题的伙伴一点帮助!;