【发布时间】:2012-01-11 05:17:06
【问题描述】:
我正在使用 Java 将文件上传到 S3 - 这是我目前得到的:
AmazonS3 s3 = new AmazonS3Client(new BasicAWSCredentials("XX","YY"));
List<Bucket> buckets = s3.listBuckets();
s3.putObject(new PutObjectRequest(buckets.get(0).getName(), fileName, stream, new ObjectMetadata()));
文件正在上传,但当我没有设置内容长度时会出现警告:
com.amazonaws.services.s3.AmazonS3Client putObject: No content length specified for stream > data. Stream contents will be buffered in memory and could result in out of memory errors.
这是我正在上传的一个文件,stream 变量是一个InputStream,我可以从中得到这样的字节数组:IOUtils.toByteArray(stream)。
所以当我尝试像这样设置内容长度和 MD5(取自 here)时:
// get MD5 base64 hash
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.reset();
messageDigest.update(IOUtils.toByteArray(stream));
byte[] resultByte = messageDigest.digest();
String hashtext = new String(Hex.encodeHex(resultByte));
ObjectMetadata meta = new ObjectMetadata();
meta.setContentLength(IOUtils.toByteArray(stream).length);
meta.setContentMD5(hashtext);
它会导致从 S3 返回以下错误:
您指定的 Content-MD5 无效。
我做错了什么?
任何帮助表示赞赏!
P.S.我在 Google App Engine 上 - 我无法将文件写入磁盘或 create a temp file,因为 AppEngine 不支持 FileOutputStream。
【问题讨论】:
-
IOUtils.toByteArray 将整个文件读取到您的内存中,因此根据文件的大小,它可能不是适当的解决方案。更好的解决方案是向文件提供者询问文件大小,然后将其流式传输到 S3,这样您就不必下载内存中的所有文件,因为您已经拥有有关大小的信息
标签: java google-app-engine amazon-s3 md5 inputstream