|
public class S3ChunkedStream extends LazySequenceInputStream {
|
|
private final AmazonS3 s3Client;
|
|
private final String bucketName;
|
|
private final String key;
|
|
private final String versionId;
|
|
private final long fileSize;
|
|
private final Map<String, String> fileMetadata;
|
|
private final long chunkSize;
|
|
|
|
private long currentPosition = 0;
|
|
|
|
public S3ChunkedStream(AmazonS3 s3Client, String bucketName, String key, long chunkSize) {
|
|
this(s3Client, bucketName, key, null, chunkSize);
|
|
}
|
|
|
|
public S3ChunkedStream(
|
|
AmazonS3 s3Client, String bucketName, String key, String versionId, long chunkSize) {
|
|
this.s3Client = s3Client;
|
|
this.bucketName = bucketName;
|
|
this.key = key;
|
|
this.versionId = versionId;
|
|
this.chunkSize = chunkSize;
|
|
|
|
ObjectMetadata objectMetadata =
|
|
s3Client.getObjectMetadata(new GetObjectMetadataRequest(bucketName, key, versionId));
|
|
this.fileSize = objectMetadata.getContentLength();
|
|
this.fileMetadata = objectMetadata.getUserMetadata();
|
|
}
|
|
|
|
public long getFileSize() {
|
|
return fileSize;
|
|
}
|
|
|
|
public Map<String, String> getFileMetadata() {
|
|
return fileMetadata;
|
|
}
|
|
|
|
@Override
|
|
protected InputStream getNextStream() {
|
|
return nextChunk();
|
|
}
|
|
|
|
InputStream nextChunk() {
|
|
if (!chunkAvailable()) {
|
|
return null;
|
|
}
|
|
|
|
long nextRangeEnd = Math.min(currentPosition + chunkSize, fileSize);
|
|
|
|
GetObjectRequest request = new GetObjectRequest(bucketName, key, versionId);
|
|
request.setRange(currentPosition, nextRangeEnd - 1);
|
|
log.trace("Get file chunk from S3 with range {}", request.getRange());
|
|
|
|
currentPosition += chunkSize;
|
|
return s3Client.getObject(request).getObjectContent();
|
|
}
|
|
|
|
boolean chunkAvailable() {
|
|
return currentPosition < fileSize;
|
|
}
|
|
}
|