gpt4 book ai didi

scala - 使用 AWS S3 Java 客户端获取目录和对象元数据

转载 作者:行者123 更新时间:2023-12-05 04:09:41 25 4
gpt4 key购买 nike

这里是 Scala 2.11,尽管这涉及 AWS S3 Java client API所以这真的是一个 Java 问题。如果有人能在 Scala 中提供答案,那将是很棒的,但我很高兴接受任何有效的 Java 答案(我总是可以在我自己的时间用 Scala 化它).


我正在尝试使用 AWS S3 客户端库连接到 S3 上的存储桶,该存储桶下面是以下目录结构:

my-bucket/
3dj439fj9fj49j/
data.json
3eidi04d40d40d/
data.json
a874739sjsww93/
data.json
...

因此,存储桶下的每个直接子对象都是一个具有字母数字名称的目录。我将这些称为“ID 目录”。这些 ID 目录中的每一个都有一个全部名为data.json 的子对象。 .

我需要完成几件事:

  1. 我需要一个字符串数组/映射/数据结构(Java Array<String> 或 Scala Array[String]),其中包含 ID 目录的所有字母数字 ID(因此元素 0 是 "3dj439fj9fj49j",元素 1 是 "3eidi04d40d40d",等等.);和
  2. 我需要一个日期数组/映射/数据结构(Java Array<Date> 或 Scala Array[Date]),其中包含每个 ID 目录对应的 data.json上次修改时间戳文件。所以如果mybucket/3dj439fj9fj49j/data.json上次修改日期/时间戳为 2017-05-29 11:19:24T,那么该日期时间将是第二个数组的第一个元素
  3. 这两个数组/映射/数据结构需要关联,这意味着我可以访问第一个 (ID) 数组的第 4 个元素并获取 my-bucket 下面的第 5 个 ID 目录,我还可以访问第二个(日期)数组的第 4 个元素并获取第 5 个 ID 目录的 data.json 的上次修改时间戳子对象

这些不一定必须是数组,它们可以是映射、元组等。如上所述,我只需要 1+ 个数据结构来保存此内容。

来自lib's Javadocs我看到一个ObjectMetadata#getLastModified字段,但我没有看到任何用于读取给定 S3Object 的父目录路径的信息(意思是 data.json 的父 ID 目录)。总而言之,我最好的尝试是失败得很惨:

val s3Client = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey))
val bucketRoot : S3Object = s3Client.getObject("myBucket","/")

// TODO: How to query 'bucketRoot' for all its child ID directories?
val idDirs : Array[S3Object] = ???

var dataMap : Map[String,Date] = null
idDirs.foreach(idDir ->
// TODO: getName() and getChildSomehow() don't exist...obviously
dataMap :+ idDir.getName() -> idDir.getChildSomehow("data.json").getObjectMetadata.getLastModified
)

那里有任何 S3 API 专家可以发现我哪里出错了,或者可以在此处将我推向正确的方向吗?提前致谢!

最佳答案

您可以调用AmazonS3#listObjects(String)获取存储桶中的对象列表。响应将包含 S3ObjectSummary对于找到的每个键。您可以调用S3ObjectSummary#getLastModified()获取最后修改的日期/时间。

这是一个将它与一些 Scala 代码联系在一起的示例。

来自 S3 存储桶的输入

> aws s3 ls --recursive s3://<REDACTED>/
2017-08-02 13:45:12 0 3dj439fj9fj49j/
2017-08-02 13:45:28 0 3dj439fj9fj49j/data.json
2017-08-02 13:45:16 0 3eidi04d40d40d/
2017-08-02 13:45:33 0 3eidi04d40d40d/data.json
2017-08-02 13:45:19 0 a874739sjsww93/
2017-08-02 13:45:37 0 a874739sjsww93/data.json

代码

import collection.JavaConverters._

import com.amazonaws.auth.AWSStaticCredentialsProvider
import com.amazonaws.auth.BasicAWSCredentials
import com.amazonaws.regions.Regions
import com.amazonaws.services.s3.AmazonS3ClientBuilder

val key = <REDACTED>
val secret = <REDACTED>
val bucketName = <REDACTED>
val region = <REDACTED>

val creds = new BasicAWSCredentials(key, secret)
val s3 = AmazonS3ClientBuilder.standard.withCredentials(new AWSStaticCredentialsProvider(creds)).withRegion(region).build

val objectSummaries = s3.listObjects(bucketName).getObjectSummaries.asScala
val dataFiles = objectSummaries.filter { _.getKey.endsWith("data.json") }
val dataDirectories = dataFiles.map(dataFile => {
val keyComponents = dataFile.getKey.split("/")
val parent = if (keyComponents.length > 1) keyComponents(keyComponents.length - 2) else "/"
(parent, dataFile.getLastModified)
})
dataDirectories.foreach(println)

输出

(3dj439fj9fj49j,Wed Aug 02 13:45:28 PDT 2017)
(3eidi04d40d40d,Wed Aug 02 13:45:33 PDT 2017)
(a874739sjsww93,Wed Aug 02 13:45:37 PDT 2017)

解释

首先,我们有一些 Bootstrap 来设置凭据和创建客户端。然后,我们发出 listObjects,这会触发对 S3 服务的调用。我们将这些结果过滤为仅以“data.json”结尾的键。然后,我们将结果映射到由父路径名和对象的最后修改日期/时间组成的元组。为了确定父路径,我们在路径分隔符上split 并检索先前的路径组件。作为一种特殊情况,如果文件位于根目录中,则我们称其父级为 "/"

我选择将结果表示为元组,但如果您愿意,可以将其更改为其他数据结构。

请注意,对于包含大量对象的存储桶,您可能需要使用 AmazonS3#listObjects(String, String)相反,这样您就可以将返回的结果限制为与特定前缀匹配的键。这将减少响应消耗的网络带宽量和响应数据所需的处理量。

要获得更多选项,您还可以考虑 AmazonS3#listObjects(ListObjectsRequest)AmazonS3#listObjectsV2(ListObjectsV2Request) .

关于scala - 使用 AWS S3 Java 客户端获取目录和对象元数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45444653/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com