1. ホーム
  2. java

[解決済み] AmazonS3 putObject with InputStream lengthの例

2023-04-23 05:29:24

質問

私は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()));

ファイルはアップロードされていますが、コンテンツの長さを設定していない場合、WARNINGが発生します。

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 を設定しようとすると ( ここで ) をこのように設定します。

// 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を使用しています - 私はディスクにファイルを書き込むことができないか、または 一時ファイルを作成する AppEngineはFileOutputStreamをサポートしていないためです。

どのように解決するのですか?

元の質問には回答がなく、私もこの同じ問題にぶつかることになったので、MD5問題の解決策は、S3は私たちが通常考えるHexエンコードされたMD5文字列を望んでいないということです。

その代わりに、私はこれをしなければなりませんでした。

// content is a passed in InputStream
byte[] resultByte = DigestUtils.md5(content);
String streamMD5 = new String(Base64.encodeBase64(resultByte));
metaData.setContentMD5(streamMD5);

本質的に彼らが MD5 値に求めているのは Base64 でエンコードされた生の MD5 バイト配列であり、Hex 文字列ではありません。私がこれに切り替えたとき、それは私にとって素晴らしく機能するようになりました。