Java,如何有效地将大型inputstream的片段分块?

Java,如何有效地将大型inputstream的片段分块?,java,amazon-web-services,Java,Amazon Web Services,我有一个可能是20-30mb的输入流。我正在尝试将块作为多部分文件上传到S3 我有可用的内容长度和输入流。我怎样才能有效地记住记忆呢 我看到有人做过这样的事,但我不确定自己是否完全理解: int contentLength=inputStreamMetadata.getContentLength(); int partSize=512*1024;//将零件大小设置为2 MB int filePosition=0; ByteArrayInputStream bais=inputStreamMeta

我有一个可能是20-30mb的输入流。我正在尝试将块作为多部分文件上传到S3

我有可用的内容长度和输入流。我怎样才能有效地记住记忆呢

我看到有人做过这样的事,但我不确定自己是否完全理解:

int contentLength=inputStreamMetadata.getContentLength();
int partSize=512*1024;//将零件大小设置为2 MB
int filePosition=0;
ByteArrayInputStream bais=inputStreamMetadata.getInputStream();
List partETags=newarraylist();
byte[]chunkedFileBytes=新字节[partSize];
for(inti=1;filePosition
特别是这篇文章:
.withInputStream(newbytearrayinputstream(bytes,0,bytesRead))

对不起,我无法(轻松)测试它,但我认为你真的很接近。。。只需“修复”和“安排”你的循环

结合您的最新代码:

int partSize = 5 * 1024 * 1024; // Set part size to 5 MB
ByteArrayInputStream bais = inputStreamMetadata.getInputStream();
List<PartETag> partETags = new ArrayList<>();
byte[] buff = new byte[partSize];
int partNumber = 1;
while (true) {//!
    int readBytes = bais.read(buff);// readBytes in [-1 .. partSize]!
    if (readBytes == -1) { //EOF
        break;
    }
    // Create the request to upload a part.
    UploadPartRequest uploadRequest = new UploadPartRequest()
                .withBucketName(bucketName)
                .withUploadId(uploadId)
                .withKey(fileName)
                .withPartNumber(partNumber++)
                .withInputStream(new ByteArrayInputStream(buff, 0, readBytes))
                .withPartSize(readBytes);

    UploadPartResult uploadResult = client.uploadPart(uploadRequest);
    partETags.add(uploadResult.getPartETag());
}
// Complete the multipart upload.... 
// https://docs.aws.amazon.com/AmazonS3/latest/dev/llJavaUploadFile.html
int partSize=5*1024*1024;//将部件大小设置为5 MB
ByteArrayInputStream bais=inputStreamMetadata.getInputStream();
List partETags=newarraylist();
字节[]buff=新字节[零件尺寸];
int partNumber=1;
虽然(正确){//!
int readBytes=bais.read(buff);//读取[-1..partSize]中的字节数!
如果(readBytes==-1){//EOF
打破
}
//创建上载零件的请求。
UploadPartRequest uploadRequest=新的UploadPartRequest()
.带bucketName(bucketName)
.withUploadId(uploadId)
.withKey(文件名)
.带零件号(零件号++)
.withInputStream(新的ByteArrayInputStream(buff,0,readBytes))
.带零件尺寸(读取字节);
UploadPartResult uploadResult=client.uploadPart(uploadRequest);
add(uploadResult.getPartETag());
}
//完成多部分上载。。。。
// https://docs.aws.amazon.com/AmazonS3/latest/dev/llJavaUploadFile.html

实际上它与。。。一个区别是:示例使用了
with file
with fileoffset
,其中使用了
with InputStream
(似乎也是正确的:使用来自当前加载块的InputStream)…我明白了,一个小问题是..最后一次迭代(
bytesRead API应该有一种启用分块传输模式的方法,这一切都可以为您完成。我更新了代码,但是将[message=Range[524288,524288+179947]长度超出了524288的界限,错误。我不知道为什么。。但是(分块)的努力值20-30mb吗!?(我在这里遇到了一些家伙@,他们通过
putObject
(知道文件大小;)…)可能不是说实话,上传速度对我来说非常慢,只有几mb,但不确定为什么。我一直认为这些部分都是并行完成的,但事实并非如此。谢谢!我会尝试一下。使用这种方法上传文件有什么速度优势吗?比如,如果我使用一个10 mb的putObjectReq或这个,它会ld可能需要大约相同的时间,对吧?-告诉我们!:)…但我怀疑是这样的…使用“上传”不是“线程/部分数”是瓶颈,而是您/客户的“上游”(以及到达aws的内容)…如果您可以“发射并忘记”…请同时“测试”并特别是(尝试避免)
waitForCompletion();
部分。我会做高级的,但是处理这个输入流,我不确定这是否可能。我想做asyc上传,但没问题-高级也提供了一个,但也渴望“元数据”(>文件大小,你知道!)在我上面的例子中,如果我读的最后一个块不是5MB,比如说500kb,那么会发生什么呢?readBytes应该是-1?