2012-10-12 6 views
8

아래 코드를 사용하여 s3 버킷의 모든 파일 이름 목록을 가져옵니다. 나는 s3에 2 개의 양동이가있다. 버킷 아래의 버킷 중 하나는 모든 파일 이름 (1000 개 이상)을 반환하지만 동일한 코드는 다른 버킷의 파일 이름을 1000 개만 반환합니다. 나는 단지 일어나고있는 일을 얻지 못한다. 동일한 코드가 하나의 버킷에서 실행되고 다른 것으로부터 실행되지 않는 이유는 무엇입니까?Amazon s3은 하나의 버킷에 대해서만 (Java sdk를 사용하여) 다른 버킷에 대해 1000 개의 항목을 반환합니까?

또한 내 버킷에는 hierarchy structure folder/filename.jpg가 있습니다.

ObjectListing objects = s3.listObjects("bucket.new.test"); 
       do { 

        for (S3ObjectSummary objectSummary : objects.getObjectSummaries()) { 
         String key = objectSummary.getKey(); 
         System.out.println(key); 


        } 
        objects = s3.listNextBatchOfObjects(objects); 
       } while (objects.isTruncated()); 

답변

4

개선하여 정상적으로 접근 @ Abhishek 자신의 대답에. 이 코드는 약간 짧습니다. 고정 변수 이름.

List<S3ObjectSummary> keyList = new ArrayList<S3ObjectSummary>(); 
ObjectListing objects = s3.listObjects("bucket.new.test"); 
keyList.addAll(objects.getObjectSummaries()); 

while (objects.isTruncated()) { 
    objects = s3.listNextBatchOfObjects(objects); 
    keyList.addAll(objects.getObjectSummaries()); 
} 
+0

근본 원인은 무엇입니까? 왜 똑같은 코드가 한 사건에 효과가 있었고 다른 사건에는 없었던 것입니까? – morsik

+0

좋은 질문입니다. 답변이 없습니다. 나는 @ Abhishek의 코드만을 가져 와서 "고정"했다. 내 유일한 추측은 그것이 양동이의 자산이라는 것입니다. – oferei

+1

s3 Java API의 "이전"버전에서 동일한 문제가 발생했습니다. 아마존은 "v2"를 발표했는데,이 문제를 해결해야합니다 : http://docs.aws.amazon.com/AmazonS3/latest/dev/ListingObjectKeysUsingJava.html 참고로's3client.listObjectsV2'와'req.setContinuationToken (result.getNextContinuationToken())'을 사용합니다. 마지막 하나는 s3에 대한 기본 REST GET 호출을 분리해야합니다 (단일 get은 기본적으로 최대 1000 개의 키를 반환하므로 http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGET.html). – morsik

4

난 그냥 대신 하나 객체 하나를 추가 할 수 에 대한 루프를 사용하는 및 addAll를 사용하는 위의 코드 변경하고 나를 위해 일했다. 당신은 단순히 목록 하여 keyList을 통해 어떤 iterater을 사용할 수 있습니다 그 후

 List<S3ObjectSummary> keyList = new ArrayList<S3ObjectSummary>(); 
     ObjectListing object = s3.listObjects("bucket.new.test"); 
     keyList = object.getObjectSummaries(); 
     object = s3.listNextBatchOfObjects(object); 

     while (object.isTruncated()){ 
      keyList.addAll(current.getObjectSummaries()); 
      object = s3.listNextBatchOfObjects(current); 
     } 
     keyList.addAll(object.getObjectSummaries()); 

:로 코드 변경입니다.

+0

keyList에 할당하는 대신 keyList.addAll (x)을 사용하는 것이 좋습니다. 이렇게하면 나중에 addAll을 사용하여 ObjectListing (getObjectSummaries에서 반환)의 private 멤버를 수정하지 않아도됩니다. 첫 줄에 이미 목록을 할당 했으므로 모든 설정이 완료되었습니다. – oferei

1

개체 (1000 개 이상의 키)를 모두 가져 오려면 마지막 키가있는 다른 패킷을 S3에 보내야합니다. 여기에 코드가 있습니다.

스칼라 개발자의
private static String lastKey = ""; 
private static String preLastKey = ""; 
... 

do{ 
     preLastKey = lastKey; 
     AmazonS3 s3 = new AmazonS3Client(new ClasspathPropertiesFileCredentialsProvider()); 

     String bucketName = "bucketname";   

     ListObjectsRequest lstRQ = new ListObjectsRequest().withBucketName(bucketName).withPrefix(""); 

     lstRQ.setMarker(lastKey); 

     ObjectListing objectListing = s3.listObjects(lstRQ); 

     // loop and get file on S3 
     for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) { 
      // get oject and do something..... 
     } 
}while(lastKey != preLastKey); 
6

, 여기에는 전체 검사를 실행하고 위의 카레를 호출하려면 공식 AWS SDK for Java

import com.amazonaws.services.s3.AmazonS3Client 
import com.amazonaws.services.s3.model.{S3ObjectSummary, ObjectListing, GetObjectRequest} 
import scala.collection.JavaConversions.{collectionAsScalaIterable => asScala} 

def map[T](s3: AmazonS3Client, bucket: String, prefix: String)(f: (S3ObjectSummary) => T) = { 

    def scan(acc:List[T], listing:ObjectListing): List[T] = { 
    val summaries = asScala[S3ObjectSummary](listing.getObjectSummaries()) 
    val mapped = (for (summary <- summaries) yield f(summary)).toList 

    if (!listing.isTruncated) mapped.toList 
    else scan(acc ::: mapped, s3.listNextBatchOfObjects(listing)) 
    } 

    scan(List(), s3.listObjects(bucket, prefix)) 
} 

를 사용하여 AmazonS3 버킷의 내용를 매핑하는 재귀 함수입니다 map() 함수를 사용하면 이미 구성된 (제대로 초기화 된) AmazonS3Client 객체 (공식 AWS SDK for Java API Reference 참조), 버킷 이름 및 첫 번째 매개 변수 목록의 접두사 이름을 전달하면됩니다. 또한 적용 할 f() 함수를 전달하여 두 번째 매개 변수 목록에 각 개체 요약을 매핑합니다. 예를 들어

val keyOwnerTuples = map(s3, bucket, prefix)(s => (s.getKey, s.getOwner)) 

그 버킷/접두사에 (key, owner) 튜플의 전체 목록을 반환합니다

또는

map(s3, "bucket", "prefix")(s => println(s)) 

같이 것 Monads in Functional Programming

관련 문제