如何在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); });
错误点分析
- 字符串语法错误:
source和dest的初始字符串缺少闭合双引号,会直接导致编译失败。 - 递归列表失效:使用
withDelimiter("/")会限制仅列出STAGED/下的直接对象,无法获取子目录(如1/、2/)内的文件。 - 复制参数错误:
CopyObjectRequest的目标桶被错误设置为字符串s3Summary,应与源桶一致为myBucket;同时直接用dest作为目标键会把所有文件都堆在PROCESSED/根目录,丢失原有子目录结构。 - 语法错误:
list.getObjectSummaries()./stream()中多了一个斜杠,正确写法是.stream()。 - 分页未处理:
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
相关产品推荐
相关产品推荐

