Java S3内容长度错误
我试图将一个文件写入S3,但遇到了一个奇怪的问题。如果我没有设置ContentLength,那么文件上传可以正常运行。我仍然可以设置MD5。但是如果我确实尝试设置内容长度(这是一个最佳实践),那么我在写入时会出现超时错误,可能是因为我发送S3的大小与实际大小不同(因此它认为它仍在等待内容) 这是我的密码Java S3内容长度错误,java,amazon-web-services,amazon-s3,Java,Amazon Web Services,Amazon S3,我试图将一个文件写入S3,但遇到了一个奇怪的问题。如果我没有设置ContentLength,那么文件上传可以正常运行。我仍然可以设置MD5。但是如果我确实尝试设置内容长度(这是一个最佳实践),那么我在写入时会出现超时错误,可能是因为我发送S3的大小与实际大小不同(因此它认为它仍在等待内容) 这是我的密码 private PutObjectResult storeFile(String key, InputStream content) { PutObjectResult result
private PutObjectResult storeFile(String key, InputStream content) {
PutObjectResult result = null;
if (content != null) {
PutObjectRequest request;
try {
ObjectMetadata metaData = new ObjectMetadata();
metaData.setContentLength(IOUtils.toByteArray(content).length);
byte[] resultByte = DigestUtils.md5(content);
String streamMD5 = new String(Base64.encodeBase64(resultByte));
metaData.setContentMD5(streamMD5);
request = new PutObjectRequest(S3_BUCKET,
key, content, metaData);
result = client.putObject(request);
} catch (AmazonS3Exception e){
LOG.error("Error writing to S3", e);
throw new RuntimeException("Error writing to S3", e);
} catch (IOException e) {
LOG.error("IO exception creating the MD5", e);
throw new RuntimeException("Error creating an MD5", e);
}
}
return result;
}
我有两套代码调用这个。一种是从输出流获取数据并将其转换为输入流
ByteArrayOutputStream stream = engine.render(template.getContent(), data);
InputStream content = new ByteArrayInputStream(stream.toByteArray());
doc.setContent(content);
另一种方法是获取Base64编码的字符串,将其反编码为字节[],然后将其转换为InputStream
String content = template.getFileContent();
byte[] contentBytes = Base64.decodeBase64(content);
PutObjectResult result = this.storeFile(key,
new ByteArrayInputStream(contentBytes));
第一种方法有效(我们从OutputStream开始,但从Base64编码字符串开始的方法无效)
我得到的错误是
AmazonS3Exception: Status Code: 400, AWS Service: Amazon S3, AWS Request ID: 018D75871D4E4F56, AWS Error Code: RequestTimeout, AWS Error Message: Your socket connection to the server was not read from or written to within the timeout period. Idle connections will be closed., S3 Extended Request ID: 04guESsxeumTi3Bh0/SfL2q8rNwDq6PObGq12imLwVZxkZs4X+8outdlYAiHr47+
你知道是什么导致了这种情况吗?问题是你读了三次
内容。这里有两次:
metaData.setContentLength(IOUtils.toByteArray(content).length);
byte[] resultByte = DigestUtils.md5(content);
第一行从流中获取所有内容,并使用setContentLength()
正确设置其长度。第二行获取空流。此行再次获取空流:
result = client.putObject(request);
只需将其读入字节数组一次,关闭流并操作数组