S3ダウンロード時にRangeを指定する
S3にアップしてあるオブジェクトをダウンロードするときに、0byte から 200 byte までを指定してダウンロードすることができます。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.Calendar; import java.util.Date; import com.amazonaws.auth.PropertiesCredentials; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.S3Object; public class S3Downloader { /** * @param args */ public static void main(String[] args) throws IOException { // TODO Auto-generated method stub AmazonS3 s3 = new AmazonS3Client(new PropertiesCredentials( S3Downloader.class.getResourceAsStream("AwsCredentials.properties"))); String bucketName = "bucketname"; String key = "filename"; ObjectMetadata metaData = s3.getObjectMetadata(bucketName, key); long contentLength = metaData.getContentLength(); System.out.println("Content Length: " + contentLength); GetObjectRequest rangeObjectRequest = new GetObjectRequest( bucketName, key); for (int i = 0 ; i < contentLength ; i=i+100) { //現在の位置から100byte先までを指定 rangeObjectRequest.setRange(i, i+100); S3Object objectPortion = s3.getObject(rangeObjectRequest); displayTextInputStream(objectPortion.getObjectContent()); } } //1行ずつ表示 private static void displayTextInputStream(InputStream input) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(input)); while (true) { String line = reader.readLine(); if (line == null) break; System.out.println(line); } } }
こちらの実行結果が以下です。
268byte(今回は非常に小さいですが)を100byteずつ分けて、ダウンロードしたものです。
途中のレンジをダウンロード中に、失敗してしまった場合に、再度同じレンジをダウンロードすることで、接続切れに対処できるかと思います。例えば5MB のレンジで順番にダウンロードする、など。
ただ、並列にダウンロードするわけではないですし、レンジごとに順番に再接続してダウンロードするので、ダウンロード速度は速くはないですね。。。ロジック次第でより安定したダウンロード処理を実現はできそうですが。
Link
http://docs.amazonwebservices.com/AmazonS3/latest/dev/RetrievingObjectUsingJava.html