web-dev-qa-db-ja.com

S3オブジェクトをファイルに書き込む方法は?

S3オブジェクト(私がキーを持っている)をファイルに書き込む最も速い方法は何ですか?私はJavaを使用しています。

16
Jason

IOUtils.copy()IOUtils.copyLarge()は素晴らしいですが、入力ストリームが-1を返すまで、入力ストリームをループする古い方法をお勧めします。どうして?以前にIOUtils.copy()を使用しましたが、S3から大きなファイルのダウンロードを開始した後、何らかの理由でそのスレッドが中断された場合、ダウンロードが停止せず、ダウンロードが停止せず、ファイル全体がダウンロードされました。

もちろん、これはS3とは関係がなく、IOUtilsライブラリだけです。

だから、私はこれを好む:

InputStream in = s3Object.getObjectContent();
byte[] buf = new byte[1024];
OutputStream out = new FileOutputStream(file);
while( (count = in.read(buf)) != -1)
{
   if( Thread.interrupted() )
   {
       throw new InterruptedException();
   }
   out.write(buf, 0, count);
}
out.close();
in.close();

注:これは、追加のライブラリが必要ないことも意味します

16
srikanta

Java 7(2011年7月に公開)なので、より良い方法があります: Files.copy() ユーティリティfrom _Java.util.nio.file_

入力ストリームからファイルにすべてのバイトをコピーします。

したがって、どちらも外部ライブラリ も必要ありません バイト配列ループ も必要ありません。以下の2つの例では、どちらもS3Object.getObjectContent()からの入力ストリームを使用しています。

_InputStream in = s3Client.getObject("bucketName", "key").getObjectContent();
_

1)指定されたパスで新しいファイルに書き込みます:

_Files.copy(in, Paths.get("/my/path/file.jpg"));
_

2)システムのデフォルトのtmpの場所にある一時ファイルに書き込みます。

_File tmp = File.createTempFile("s3test", "");
Files.copy(in, tmp.toPath(), StandardCopyOption.REPLACE_EXISTING);
_

(既存のファイルを置き換えるオプションを指定しないと、FileAlreadyExistsExceptionを取得します。)

また、 getObjectContent() Javadocs 入力ストリームを閉じるように促します

S3Objectを取得する場合、オブジェクトのコンテンツはメモリにバッファリングされず、Amazon S3から直接ストリーミングされるため、この入力ストリームをできるだけ早く閉じる必要があります。さらに、このストリームを閉じることができないと、リクエストプールがブロックされる可能性があります。

したがって、すべてをtry-catch-finallyでラップし、finallyブロックでin.close();を実行するのが最も安全なはずです。

上記は、Amazonの公式SDKを使用していることを前提としています( _aws-Java-sdk-s3_ )。

31
Jonik

AmazonS3Clientクラスには次のメソッドがあります。

_S3Object getObject(String bucketName, String key)
_

返されるS3Objectにはメソッドがあります...

_Java.io.InputStream getObjectContent()
_

..オブジェクトコンテンツをストリームとして取得します。次のように、ApacheCommonsのIOUtilsを使用します。

IOUtils.copy(s3Object.getObjectContent(), new FileOutputStream(new File(filepath)));

7
Jonathan

TransferManagerを使用したこの1つのライナーはどうですか?

TransferManagerBuilder.defaultTransferManager
  .download("bucket-name", "key", new File("."))
4
Joan