目前,我正在使用 Java 的 S3 SDK 中的 AWS 的 TransferManager 触发从 SFTP 服务器到 S3 的上传。我触发此上传的方式如下:
(伪代码...)
@Autowired
TransferManager transferManager;
@Autowired
SftpStreamFactory sftpStreamFactory;
SftpStream sftpStream = sftpStreamFactory.createStream(filePath);
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(sftpStream.getSizeBytes());
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, sftpStream.getStream(), objectMetadata);
putObjectRequest.setGeneralProgressListener(new UploadBeginEndNotificationListener(uploadRequest, statusNotifier));
transferManager.upload(putObjectRequest);
这是 的定义SftpStream
:
@AllArgsConstructor
public class SftpStreamFactory {
@Getter
@AllArgsConstructor
public static class SftpStream {
private final long sizeBytes;
private final InputStream stream;
}
private final SftpRemoteFileTemplate sftpTemplate;
private final SftpProperties sftpProperties;
public SftpStream createStream(Path relativePath) {
return sftpTemplate.<SftpStream, ChannelSftp>executeWithClient(session -> createStream(session, relativePath));
}
SftpStream createStream(ChannelSftp channelSftp, Path relativePath) {
String path = sftpProperties.getRoot().resolve(relativePath).toString();
try {
SftpATTRS fileAttrs = channelSftp.lstat(path);
long size = fileAttrs.getSize();
return new SftpStream(size, channelSftp.get(path));
}
catch (SftpException e) {
throw new UncheckedIOException(new NestedIOException("SFTP Error", e));
}
}
}
这种上传方法效果很好。但是,如果分段上传在中间被暂停/取消/以其他方式中止,我们希望从中断的地方继续,而不是重新开始。我们知道 TransferManagersresumeUpload
方法需要一个PersistableUpload
.
但是,在 javadoc 中PersistableUpload
,它期望file
在构造函数中传递一个路径,然后尝试从中创建一个File
对象:
https ://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws /services/s3/transfer/PersistableUpload.html
我们想知道的是,在没有这个文件对象的情况下是否可以恢复上传,我们无法从我们的ChannelSftp
. 也就是说,我们可以从流而不是文件恢复上传吗?或者我们是否必须切换到使用低级 s3 api 来执行这样的恢复。任何建议表示赞赏。
编辑 - 进行了更多研究,甚至为已经存在的上传传递了 UploadId,如果没有文件,doUpload 方法将抛出异常。有任何想法吗?