使用Appercept AWS SDK for Delphi获取存储桶对象列表返回0的问题
Delphi AWS S3 SDK 获取存储桶对象列表返回0的解决方法
问题说明
连接S3兼容存储(https://s3.storage.selcloud.ru)时,能成功获取根存储桶列表,但通过Bucket.Objects.Count获取存储桶内对象数量始终返回0,实际桶内存在3个对象。Python的boto3工具可以正常读取这些对象,需要修正Delphi代码实现。
原因分析
ListBuckets接口仅用于获取存储桶的元数据列表(如存储桶名称、创建时间),并不会返回存储桶内的对象信息。SDK返回的Bucket对象中,Objects属性默认是空集合,这是正常的设计逻辑,必须单独调用对象列表接口才能获取桶内的文件。
解决方案
使用ListObjectsV2方法(推荐,替代旧版ListObjects)获取指定存储桶的对象列表,同时处理可能的分页场景(当对象数量超过1000时需要分页)。
修改后的代码示例
uses AWS.S3, AWS.Core, AWS.S3.Model; ... procedure TMainForm.FormCreate(Sender: TObject); var opt: IAWSOptions; ListBucketsResponse: IListBucketsResponse; ListObjectsResponse: IListObjectsV2Response; ContinuationToken: string; begin ReportMemoryLeaksOnShutdown := true; opt := TAWSOptions.Create; opt.AccessKeyId := '*****'; opt.SecretAccessKey := '*****'; opt.Endpoint := TAWSEndpoint.Create('https://s3.storage.selcloud.ru'); opt.Region := 'ru-1'; s3aws := TS3Client.Create(opt); // 获取存储桶列表 ListBucketsResponse := s3aws.ListBuckets; StatusMemo.Lines.Add('Root bucket(s):'); for var Bucket in ListBucketsResponse.Buckets do begin StatusMemo.Lines.Add( '- ' + Bucket.Name ); // 单独获取当前存储桶的对象列表 ContinuationToken := ''; repeat // 构建请求参数 var Request := TListObjectsV2Request.Create; try Request.BucketName := Bucket.Name; Request.ContinuationToken := ContinuationToken; // 调用接口获取对象 ListObjectsResponse := s3aws.ListObjectsV2(Request); // 输出对象数量和详情 StatusMemo.Lines.Add( '- 当前页对象数: ' + IntToStr(ListObjectsResponse.S3Objects.Count) ); for var S3Obj in ListObjectsResponse.S3Objects do StatusMemo.Lines.Add( ' - ' + S3Obj.Key ); // 更新分页标记 ContinuationToken := ListObjectsResponse.NextContinuationToken; finally Request.Free; end; until ContinuationToken.IsEmpty; // 没有更多分页时停止 end; end;
关键点说明
- 使用
TListObjectsV2Request指定要查询的存储桶名称 - 通过
NextContinuationToken处理分页,确保获取所有对象 - 对象信息在
ListObjectsResponse.S3Objects集合中,而非Bucket.Objects
内容的提问来源于stack exchange,提问作者Aleksey Aleshkov
相关产品推荐
相关产品推荐

