【问题标题】:How to get the oldest added object from Amazon S3 Bucket?如何从 Amazon S3 存储桶中获取最旧的添加对象?
【发布时间】:2013-04-07 16:11:58
【问题描述】:

我在亚马逊存储桶中有一个文件夹,里面有一些对象。

如何获取最旧的添加对象?

 public FileMetaData Poll()
        {
            var config = new AmazonS3Config();
            config.ServiceURL = "s3.amazonaws.com";
            config.CommunicationProtocol = Protocol.HTTP;

            string bucketName = "bucketname1";
            string accessKey = "accesskey1";
            string secretKey = "secretkey1";

            Amazon.S3.AmazonS3 client = AWSClientFactory.CreateAmazonS3Client(accessKey,
                secretKey,
                config);

            var request = new GetObjectRequest();
            request.WithBucketName(bucketName);

            // how to get the oldest object?

            GetObjectResponse response = client.GetObject(request);

            // todo
            return null;
        }

我已经尝试了以下代码,它运行良好,但问题是它加载了所有对象,然后找到最旧的对象,我认为这是一种不好的做法:

var request = new ListObjectsRequest()
                .WithBucketName(bucketName)
                .WithPrefix(this._folderPath);

            ListObjectsResponse response = client.ListObjects(request);

            S3Object s3Object = response.S3Objects
                .Where(p => !p.Key.EndsWith("_$folder$"))
                .OrderBy(k => k.LastModified).FirstOrDefault();

            var getObjectRequest = new GetObjectRequest()
                .WithBucketName(bucketName)
                .WithKey(s3Object.Key);

            GetObjectResponse getObjectResponse = client.GetObject(getObjectRequest);

            // provider 
            string provider = getObjectResponse.Metadata.Get("x-amz-meta-provider");
            string site = getObjectResponse.Metadata.Get("x-amz-meta-sitename");
            string identifier = s3Object.Key.Remove(0, this._folderPath.Length);
            string xmlData = new StreamReader(getObjectResponse.ResponseStream, true).ReadToEnd();

            return new FileMetaData()
                {
                    Identifier = identifier,
                    Provider = provider,
                    SiteName = site,
                    XmlData = xmlData
                };

【问题讨论】:

    标签: c# amazon-web-services amazon-s3 storage


    【解决方案1】:

    它会加载所有对象,然后找到最旧的对象

    实际上,您并没有加载所有对象,而是列出了它们(很大的不同。)S3 不是数据库(也不是文件系统),因此如果需要,您必须构建自己的本地索引容易接近。 (或使用 DynamoDB、SimpleDB、RDS 等)

    更改您的密钥以包含日期/时间不会帮助您很多。您可以使用前缀和分隔符来帮助缩小搜索范围。 (即,如果每个文件都以“YYYY-MM-DD-HHMM”开头,您可以将分隔符设置为“-”以查找最早的年份,然后将前缀=“YYYY-”和分隔符“-”设置为查找最早的月份等.)

    【讨论】:

      【解决方案2】:

      您的代码看起来不错。 “列出对象请求”只会浪费几秒钟,但据我所知,这是强制性的。

      我在您的代码中看到的一个问题是您没有处理每个请求返回的最大密钥数量为 1000 个这一事实。如果您可能有更多的密钥,那么您必须检查列表是否被截断,将请求标记更改为下一个并发出更多请求。

          var request = new ListObjectsRequest()
                          .WithBucketName(bucketName)
                          .WithPrefix(this._folderPath);
      
          ListObjectsResponse response;
          S3Object s3Object = null;
          do
          {
              response = client.ListObjects(request);
              S3Object tempS3Object = response.S3Objects
                  .Where(p => !p.Key.EndsWith("_$folder$"))
                  .OrderBy(k => k.LastModified).FirstOrDefault();
              if (s3Object != null)
              {
                  if (s3Object.LastModified < tempS3Object.LastModified)
                      s3Object = tempS3Object;
              }
              else s3Object = tempS3Object;
      
              request.Marker = response.NextMarker;
          } while (response.IsTruncated);
      
          var getObjectRequest = new GetObjectRequest()
              .WithBucketName(bucketName)
              .WithKey(s3Object.Key);
      
          GetObjectResponse getObjectResponse = client.GetObject(getObjectRequest);
      
          // provider 
          string provider = getObjectResponse.Metadata.Get("x-amz-meta-provider");
          string site = getObjectResponse.Metadata.Get("x-amz-meta-sitename");
          string identifier = s3Object.Key.Remove(0, this._folderPath.Length);
          string xmlData = new StreamReader(getObjectResponse.ResponseStream, true).ReadToEnd();
      
          return new FileMetaData()
          {
              Identifier = identifier,
              Provider = provider,
              SiteName = site,
              XmlData = xmlData
          };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-07
        • 2020-01-21
        • 2013-08-23
        • 1970-01-01
        • 1970-01-01
        • 2012-04-12
        相关资源
        最近更新 更多