我正在尝试将文件写入 S3,但遇到了一个奇怪的问题。如果我不设置 ContentLength,则文件上传运行良好。而且我仍然可以设置MD5。但是,如果我确实尝试设置内容长度(这是一个最佳实践),那么我会在写入时收到超时错误,大概是因为我发送 S3 的大小和实际大小不同(所以它认为它仍然是等待内容。)
这是我的代码。
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 编码的字符串,将其解编码为 byte[],然后将其转换为 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+
关于可能导致这种情况的任何想法?