簡體   English   中英

AWS S3 - 列出沒有前綴的文件夾中的所有對象

[英]AWS S3 - Listing all objects inside a folder without the prefix

我在檢索AWS S3中文件夾內的所有對象(文件名)時遇到問題。 這是我的代碼:

ListObjectsRequest listObjectsRequest = new ListObjectsRequest()
            .withBucketName(bucket)
            .withPrefix(folderName + "/")
            .withMarker(folderName + "/")

    ObjectListing objectListing = amazonWebService.s3.listObjects(listObjectsRequest)

    for (S3ObjectSummary summary : objectListing.getObjectSummaries()) {
        print summary.getKey()
    }

它返回正確的對象但是帶有前綴,例如foldename / filename

我知道我可以使用java或substring來排除前綴,但我只想知道AWS SDK中是否有方法。

那沒有。 Linked是所有可用方法的列表。 這背后的原因是S3設計。 S3沒有“子文件夾”。 相反,它只是一個文件列表,其中文件名是“前綴”加上您想要的文件名。 GUI顯示與存儲在“文件夾”中的窗口類似的數據,但S3中沒有文件夾邏輯。

http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/model/S3ObjectSummary.html

最好的辦法是用“/”拆分並取出數組中的最后一個對象。

對於Scala開發人員,這里是使用官方AWS SDK for Java執行完整掃描和 AmazonS3存儲桶內容映射的遞歸函數

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 map()函數,只需在第一個參數列表中傳遞已構造的(並且已正確初始化的)AmazonS3Client對象(請參閱官方AWS SDK for Java API Reference ),存儲桶名稱和前綴名稱。 還要傳遞要應用的函數f()以映射第二個參數列表中的每個對象摘要。

例如

map(s3, bucket, prefix) { s => println(s.getKey.split("/")(1)) }

將打印所有文件名(不帶前綴)

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

將返回該bucket /前綴中的(key, owner, size)元組的完整列表

val totalSize = map(s3, "bucket", "prefix")(s => s.getSize).sum

將返回其內容的總大小(注意在表達式結尾處應用的額外sum()折疊函數;-)

您可以將map()Monads在函數式編程中通常采用的許多其他函數結合起來

這段代碼幫助我找到我的桶的子目錄。

示例: - “Testing”是我的存儲桶名稱,其中包含“kdblue@gmail.com”文件夾,然后包含“IMAGE”文件夾,其中包含圖像文件。

     ArrayList<String> transferRecord = new ArrayList<>();    

     ListObjectsRequest listObjectsRequest =
                            new ListObjectsRequest()
                                    .withBucketName(Constants.BUCKET_NAME)
                                    .withPrefix("kdblue@gmail.com" + "/IMAGE");

      ObjectListing objects = s3.listObjects(listObjectsRequest);
        for (;;) {
                    List<S3ObjectSummary> summaries = 
                    objects.getObjectSummaries();
                        if (summaries.size() < 1) {
                            break;
                        }

                       for(int i=0;i<summaries.size();i++){
                            ArrayList<String> file = new ArrayList<>();

                            file.add(summaries.get(i).getKey());
                            transferRecord.add(file);
                        }

                        objects = s3.listNextBatchOfObjects(objects);
               }

我希望這可以幫助你。

只是為了跟進上面的評論 - “這里它是執行完整掃描和映射的遞歸函數” - 如果存儲桶中有超過1000個密鑰,則代碼中存在一個錯誤(如@Eric突出顯示)。 修復實際上非常簡單,需要將mapped.toList與acc合並。

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

  def scan_s3_bucket(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) {
      acc ::: mapped.toList
    } else {
      println("list extended, more to go: new_keys '%s', current_length '%s'".format(mapped.length, acc.length))
      scan_s3_bucket(acc ::: mapped, s3.listNextBatchOfObjects(listing))
    }
  }

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

剪下來對我來說效果很好。 參考: https//codeflex.co/get-list-of-objects-from-s3-directory/

    List<String> getObjectslistFromFolder(String bucketName, String folderKey, AmazonS3 s3Client) {

    ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName(bucketName)
            .withPrefix(folderKey + "/");

    List<String> keys = new ArrayList<String>();

    ObjectListing objects = s3Client.listObjects(listObjectsRequest);
    for (;;) {
        List<S3ObjectSummary> summaries = objects.getObjectSummaries();
        if (summaries.size() < 1) {
            break;
        }

        // summaries.forEach(s -> keys.add(s.getKey()));
        // changed project compliance to jre 1.8
        summaries.forEach(s -> keys.add(s.getKey()));

        objects = s3Client.listNextBatchOfObjects(objects);
    }

    return keys;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM