본문 바로가기
컴퓨터관련

Java 이용하여 S3 progress download 하기

by 기록이답이다 2017. 1. 27.
반응형

AWS S3를 이용하는데 s3에 있는 파일을 다운로드를 해야 할때 아래와 같이 하면 된다.


우선 AWS-LIB를 (https://aws.amazon.com/ko/sdk-for-java/) 여기에서 받아서

프로젝트에 import한다.


s3에 있는 파일을 java를 이용하여 다운로드하는 단계는 다음과 같다.


1. ProfileCredentialsProvider 를 이용해서 AWSCredentials 을 얻어온다.

credentials = new ProfileCredentialsProvider( credential파일위치, 프로파일이름 ).getCredentials(  );


~/.aws/  디렉토리에  credentials 파일을 만들어두면 아래와 같이 하지 않고 위와 같이 바로 적용할 수 있다.

credentials = new ProfileCredentialsProvider().getCredentials();


credential 파일은 다음과 같이 만들 수 있다.

메모장을 열어 아래의 내용을 입력하면 된다.

[default] <- profile의 이름이다.

aws_access_key_id=aws_access_key_id 를 입력한다. aws_secret_access_key=aws_secret_access_key 를 입력한다.


위에서 얻어온 credentials를 가지고 AmazonS3 객체를 생성후 Region을 설정해준다.

AmazonS3 s3 = new AmazonS3Client(credentials);
Region usWest2 = Region.getRegion(Regions.US_EAST_1);
s3.setRegion(usWest2);


위의 단계가 AmazonS3 객체를 얻어와 region을 설정하는 단계이다.

이제 s3 객체를 얻어왔으니 파일을 다운로드할 수 있다.

s3.getObject(new GetObjectRequest(bucketName, 다운받을파일의 keyName ), new File( 저장될위치 ));


위와같이 해도 되지만... ProgressListener를 이용하여 얼만큼 다운로드 받았는지 확인하고 싶을것이다.

다운로드에 progressListener를 지정하는것도 이전 블로그글 'AWS S3 Uploader Progress 이용하여 uploading 하기(http://bugnote.tistory.com/60)처럼하면 된다.


단지 PutObjectRequest 대신에 GetObjectRequest를 사용하면 된다.



s3객체를 얻어왔으니 TransferManager 와 GetObjectRequest를 이용하여 다운로드를 구현하면 된다.


TransferManager와 GetObjectRequest객체를 생성한다.

TransferManager tx = new TransferManager(s3);
GetObjectRequest request = new GetObjectRequest(bucketName, keyName);


transferManager 객체를 이용하여 getObject객체를 다운로드한다.

Download download = tx.download(request);
double totalSize = download.getProgress().getTotalBytesToTransfer(); // 전체 파일사이즈
request.withGeneralProgressListener(progressListener); // progressListener 지정


progressListener는 아래와 같다.


    prevPer = -1;
    public ProgressListener progressListener = new ProgressListener() {
    	double trans = 0;
        public void progressChanged(ProgressEvent progressEvent) {
            if (download == null) return;

synchronized(this) {
            trans += progressEvent.getBytesTransferred();
      }
            int currPer = (int)download.getProgress().getPercentTransferred();
            if(prevPer < currPer) {
                System.out.println(request.getKey() + " - " + getNumberFormat(trans/1000) + " / " + getNumberFormat(totalSize/1000) + " : " + currPer + "% - " + parent.getFinCnt());
            }
            prevPer = currPer;
            
            switch (progressEvent.getEventCode()) {
            case ProgressEvent.COMPLETED_EVENT_CODE:
            	System.out.println("100%"); // 다운완료
            	per = 0;
            	trans = 0;
                break;
            case ProgressEvent.FAILED_EVENT_CODE:
                try {
                    AmazonClientException e = download.waitForException(); // exception발생
                } catch (InterruptedException e) {}
                break;
            }
        }
    };


전체소스는 다음과 같다.

package bugnote.download.s3;

import java.io.File;
import java.text.DecimalFormat;

import com.amazonaws.AmazonClientException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.event.ProgressEvent;
import com.amazonaws.event.ProgressListener;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.Download;

public class S3Downloader {
	private AmazonS3 s3;
	private String bucketName;
	private Download download;
	private PutObjectRequest request = null;
	private static TransferManager tx;
	private double totalSize;
	
	public static void main(String[] args) {
		new S3Downloader();
	}
	
	public S3Downloader() {
		
		AWSCredentials credentials = new ProfileCredentialsProvider("credential파일위치", "프로파일이름").getCredentials();
		s3 = new AmazonS3Client(credentials);
		Region region = Region.getRegion(Regions.US_EAST_1);
		s3.setRegion(region);
		
		this.bucketName = "s3 버킷이름";
		this.tx = new TransferManager(s3);
		
		File file = new File("업로드할파일");
		doDownload(file);
	}

	public void doDownload(File f) {
		// 디렉토리/디렉토리/파일명 으로 keyname을 주기위해 파일명을 제외한 디렉토리를 구한다.
    	request = new GetObjectRequest(bucketName, s3KeyName).withGeneralProgressListener(progressListener);
    	
    	download = this.tx.download(request);
    	totalSize = download.getProgress().getTotalBytesToTransfer();
	}

	private String numberFormat(Object value) {
		DecimalFormat df = new DecimalFormat("#.##");
		return df.format( value );
	}
	
	int prevPer = -1;
    public ProgressListener progressListener = new ProgressListener() {
    	double trans = 0;
		public void progressChanged(ProgressEvent progressEvent) {
            if (download == null) return;

            synchronized (this) {
            	trans += progressEvent.getBytesTransferred();
            	int currPer = (int)download.getProgress().getPercentTransferred();
            	if(prevPer < currPer) {
            		System.out.println(request.getKey() + " - " + numberFormat(trans/1000) + " / " + numberFormat(totalSize/1000) + " : " + currPer + "%");
            	}
            	prevPer = currPer;
            }
            
            switch (progressEvent.getEventCode()) {
            case ProgressEvent.COMPLETED_EVENT_CODE:
            	System.out.println("100%"); // 전송완료
            	trans = 0;
                break;
            case ProgressEvent.FAILED_EVENT_CODE:
                try {
                    AmazonClientException e = download.waitForException();
                } catch (InterruptedException e) {}
                break;
            }
        }
    };
}




java를 이용한 s3에 file download 종료!!!



반응형