You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AWS S3中复制完整文件夹结构?代码实现遇阻求助

AWS S3 目录结构复制问题排查与解决

问题场景

我的AWS S3存储桶有如下目录结构:

源路径

  • 2022-09-09/EOD/9898/STAGED/1/abc.txt
  • 2022-09-09/EOD/9898/STAGED/1/test.csv
  • 2022-09-09/EOD/9898/STAGED/2/abc1.txt
  • 2022-09-09/EOD/9898/STAGED/2/test1.csv

目标路径(预期)

  • 2022-09-09/EOD/9898/PROCESSED/1/abc.txt
  • 2022-09-09/EOD/9898/PROCESSED/1/test.csv
  • 2022-09-09/EOD/9898/PROCESSED/2/abc1.txt
  • 2022-09-09/EOD/9898/PROCESSED/2/test1.csv

需求是将STAGED目录下的内容完整复制到PROCESSED目录,保留所有子目录结构。以下是我尝试的Java代码,但未达到预期效果:

String dest=("2022-09-09/EOD/9898/).concat("PROCESSED").concat("/");
String source=("2022-09-09/EOD/9898/).concat("STAGED").concat("/");

ListObjectRequest lst=new ListObjectRequest().withBucketName("myBucket").withPrefix(source).withDelimiter("/");
ObjectListing list=amazonS3.listObjects(lst)
list.getObjectSummaries()./stream().forEach(s3Summary->{

CopyObjectRequest cor=new CopyObjectRequest ("myBucket",s3Summary.getKey(),"s3Summary",dest);
amazonS3.copyObject(cor);
});

错误点分析

  1. 字符串语法错误:source和dest的初始字符串缺少闭合双引号,会直接导致编译失败。
  2. 递归列表失效:使用withDelimiter("/")会限制仅列出STAGED/下的直接对象,无法获取子目录(如1/、2/)内的文件。
  3. 复制参数错误:CopyObjectRequest的目标桶被错误设置为字符串s3Summary,应与源桶一致为myBucket;同时直接用dest作为目标键会把所有文件都堆在PROCESSED/根目录,丢失原有子目录结构。
  4. 语法错误:list.getObjectSummaries()./stream()中多了一个斜杠,正确写法是.stream()。
  5. 分页未处理:listObjects可能返回分页结果,仅单次调用无法获取所有对象。

修正后的代码

// 修正字符串引号问题,定义源前缀和目标前缀
String sourcePrefix = "2022-09-09/EOD/9898/STAGED/";
String targetPrefix = "2022-09-09/EOD/9898/PROCESSED/";
String bucketName = "myBucket";

ListObjectsRequest listRequest = new ListObjectsRequest()
        .withBucketName(bucketName)
        .withPrefix(sourcePrefix); // 移除分隔符,递归获取所有子对象

ObjectListing objectListing = amazonS3.listObjects(listRequest);

// 处理分页结果,确保获取所有文件
while (true) {
    objectListing.getObjectSummaries().stream()
            .forEach(s3Summary -> {
                // 跳过S3的空"目录"对象(避免无效复制)
                if (s3Summary.getKey().endsWith("/")) {
                    return;
                }
                // 生成目标键:替换源前缀为目标前缀,自动保留子目录结构
                String targetKey = s3Summary.getKey().replaceFirst(sourcePrefix, targetPrefix);
                // 构造正确的复制请求
                CopyObjectRequest copyRequest = new CopyObjectRequest(
                        bucketName,
                        s3Summary.getKey(),
                        bucketName,
                        targetKey
                );
                amazonS3.copyObject(copyRequest);
            });

    // 检查是否还有更多分页结果
    if (!objectListing.isTruncated()) {
        break;
    }
    objectListing = amazonS3.listNextBatchOfObjects(objectListing);
}

代码说明

  • 移除分隔符:不设置withDelimiter,让S3递归返回所有以sourcePrefix开头的对象,包括子目录内的文件。
  • 目标键生成:通过replaceFirst将源键中的STAGED/替换为PROCESSED/,自动保留原有子目录层级。
  • 分页处理:循环获取所有分页结果,确保不会遗漏任何文件。
  • 跳过目录对象:S3中没有实际目录,后缀为/的是空对象,跳过这些对象避免无效复制操作。

内容的提问来源于stack exchange,提问作者sushant shekhar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 02:25:17