2012-10-12 9 views
8

मैं एस 3 बाल्टी से सभी फ़ाइल नामों की सूची प्राप्त करने के लिए नीचे उल्लिखित कोड का उपयोग कर रहा हूं। मेरे पास एस 3 में दो बाल्टी है। कोड के नीचे एक बाल्टी के लिए सभी फ़ाइल नाम (1000 से अधिक) लौटाते हैं, लेकिन एक ही कोड दूसरी बाल्टी के लिए केवल 1000 फ़ाइल नाम देता है। मैं बस क्या हो रहा है नहीं मिलता है। एक ही कोड एक बाल्टी के लिए क्यों चल रहा है और दूसरे के लिए नहीं?अमेज़ॅन एस 3 एक बाल्टी के लिए केवल 1000 प्रविष्टियां देता है और सभी एक और बाल्टी के लिए (जावा एसडीके का उपयोग कर)?

इसके अलावा मेरी बाल्टी में पदानुक्रम संरचना फ़ोल्डर/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

सुधार दृष्टिकोण अभिषेक के अपने उत्तर पर @ यह कोड थोड़ा छोटा है। निश्चित चर नाम भी।

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

यह एक अच्छा सवाल है, जिसका मेरे पास जवाब नहीं है। मैंने केवल @ अभिषेक का कोड लिया और इसे "निश्चित" किया। मेरा एकमात्र अनुमान यह है कि यह बाल्टी की संपत्ति है। – oferei

+1

मुझे एस 3 जावा एपीआई के "पुराने" संस्करण के साथ एक ही समस्या है। अमेज़ॅन ने "v2" पेश किया, जिसे इस मुद्दे को हल करना चाहिए: http://docs.aws.amazon.com/AmazonS3/latest/dev/ListingObjectKeysUsingJava।एचटीएमएल नोट, यह 's3client.listObjectsV2' और' req.setContinuationToken (result.getNextContinuationToken()) का उपयोग करता है। आखिरी व्यक्ति को अलग-अलग अंतर्निहित आरईएसटी को एस 3 पर कॉल करना चाहिए (क्योंकि एकल डिफ़ॉल्ट रूप से 1000 कुंजी तक लौटाता है, http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGET.html) – morsik

4

मैं सिर्फ कोड ऊपर बदल दिया है बजाय एक के बाद वस्तु एक जोड़ने के लिए के लिए पाश का उपयोग करने का addAll उपयोग करने के लिए और यह मेरे लिए काम किया।

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

उसके बाद आपको बस अपनी सूची keyList पर कोई iterater उपयोग कर सकते हैं: के रूप में कोड परिवर्तन कर रहे हैं।

+0

मैं keyList को निर्दिष्ट करने के बजाय keyList.addAll (x) का उपयोग करने का सुझाव देता हूं। इस तरह आप addAll का उपयोग कर ऑब्जेक्टलिस्टिंग (जिसे GetObjectSummaries द्वारा वापस किया गया था) के एक निजी सदस्य को संशोधित नहीं कर रहे हैं। और, चूंकि आप पहले पंक्ति में पहले से ही एक सूची आवंटित कर चुके हैं, इसलिए आप पूरी तरह से सेट हैं। – 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)) 
} 

का उपयोग करके उपरोक्त curried आह्वान करने के लिए नक्शे एक AmazonS3 बाल्टी की सामग्री का को पुनरावर्ती क्रिया है map() फ़ंक्शन, पहले से ही निर्मित (और उचित रूप से प्रारंभ किया गया) अमेज़ॅनएस 3 क्लाइंट ऑब्जेक्ट (आधिकारिक AWS SDK for Java API Reference देखें), बाल्टी नाम और पहले पैरामीटर सूची में उपसर्ग नाम को पास करें। फ़ंक्शन f() भी पास करें जिसे आप दूसरी पैरामीटर सूची में प्रत्येक ऑब्जेक्ट सारांश को मैप करने के लिए आवेदन करना चाहते हैं।

उदाहरण के लिए

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

कि बाल्टी/उपसर्ग में (key, owner) tuples की पूरी सूची वापस आ जाएगी

या

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

हैं जैसा कि आप सामान्य रूप से द्वारा Monads in Functional Programming

संबंधित मुद्दे