S3ダウンロード時にRangeを指定する

S3にアップしてあるオブジェクトをダウンロードするときに、0byte から 200 byte までを指定してダウンロードすることができます。

それを試したときの、Javaソースコードが以下です。

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);
		}
	}

}

こちらの実行結果が以下です。

f:id:kenjifunasaki:20121218152858p:plain

268byte(今回は非常に小さいですが)を100byteずつ分けて、ダウンロードしたものです。

途中のレンジをダウンロード中に、失敗してしまった場合に、再度同じレンジをダウンロードすることで、接続切れに対処できるかと思います。例えば5MB のレンジで順番にダウンロードする、など。

ただ、並列にダウンロードするわけではないですし、レンジごとに順番に再接続してダウンロードするので、ダウンロード速度は速くはないですね。。。ロジック次第でより安定したダウンロード処理を実現はできそうですが。

Link
http://docs.amazonwebservices.com/AmazonS3/latest/dev/RetrievingObjectUsingJava.html