【问题标题】:How to use AWS Java SDK to fetch objects list with query as s3api?如何使用 AWS Java SDK 以 s3api 查询获取对象列表?
【发布时间】:2020-02-23 09:36:41
【问题描述】:

我正在使用 AWS java SDK 进行开发。我想获得一个带有过滤器的对象列表,例如按上次修改日期过滤器。我可以在 s3api 上看到这个功能,如下所示

aws s3api list-objects 
            --bucket "myS3-BucketName" 
            --query "Contents[?LastModified>=`2018-02-01`].{Key: Key, Size: Size, LastModified: LastModified}" 
            --max-items 10"

我在 Java SDK 中找不到类似的解决方案。如何使用 Java SDK 完成这项工作?

【问题讨论】:

    标签: java amazon-web-services amazon-s3 aws-sdk


    【解决方案1】:

    使用 AWS SDK for Java 的 v2,我创建了以下实用程序方法:

    /**
     * Gets S3 objects that reside in a specific bucket and whose keys conform to the 
     * specified prefix using v2 of the AWS Java SDK.
     * <br><br>
     * The objects returned will have a last-modified date between {@code start} and 
     * {@code end}.
     * <br><br>
     * Any objects that have been modified outside of the specified date-time range will 
     * not be returned.
     *
     * @param s3Client The v2 AWS S3 client used to make the request to S3.
     * @param bucket   The bucket where the S3 objects are located.
     * @param prefix   The common prefix that the keys of the S3 objects must conform to.
     * @param start    The objects returned will have been modified after this instant.
     * @param end      The objects returned will have been modified before this instant.
     * @return A {@link Stream} of {@link S3Object} objects.
     */
    public static Stream<S3Object> getObjects(S3Client s3Client, String bucket, 
                                              String prefix, Instant start, 
                                              Instant end) {
        return s3Client.listObjectsV2Paginator(builder -> builder.bucket(bucket)
                       .prefix(prefix).build())
                .stream()
                .map(ListObjectsV2Response::contents)
                .flatMap(List::stream)
                .filter(s3Object -> {
                    Instant lastModified = s3Object.lastModified();
                    return !start.isAfter(lastModified) && !end.isBefore(lastModified);
                });
    }
    

    以下代码在逻辑上等同于您的示例:

    S3Client s3Client = S3Client.create();
    String bucket = "myS3-BucketName";
    Instant before = Instant.parse("2018-02-01T00:00:00Z");
    Instant after = Instant.MAX;
    
    Stream<S3Object> firstTenObjects = 
        getObjects(s3Client, bucket, "", before, after).limit(10);
    

    您可以使用以下方法从Stream中的每个S3Object中获取您要查找的数据:

    【讨论】:

    • 嗨@jacob-g,感谢您的解决方案。一件事我想确认这个方法是否在本地过滤?
    • @RayChen 是;据我所知,AWS Java SDK 不支持远程过滤,但它应该不会那么贵很多。
    • 嗨@jacob-G,我们改为使用 S3 通知 + Lambda,因为我们确实有很多对象。感谢您的解决方案。
    • @JacobG。 “远程过滤”是指在 AWS 端过滤记录并且仅将符合条件的记录返回给客户端?这基本上是我希望发生的事情,因为合格记录的数量是记录总数的几十(如果不是几百)倍
    • @mangusta 没错。我没有及时了解适用于 S3 的 AWS 开发工具包,所以我不确定是否添加了该功能。
    猜你喜欢
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 2016-03-11
    • 2016-02-06
    • 1970-01-01
    • 2018-07-09
    • 2020-07-10
    相关资源
    最近更新 更多