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

如何使用Java AWS SDK在S3存储桶内压缩指定目录对象

在S3中压缩Demo/目录下对象的Java实现方案

Amazon S3没有原生API支持直接在桶内对已有对象进行压缩操作,你需要通过下载对象→本地压缩→上传压缩包的流程来实现,以下是基于AWS Java SDK v2的具体实现步骤:

1. 引入依赖

确保项目中包含AWS S3 SDK的依赖,Maven配置示例:

<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>s3</artifactId>
    <version>2.25.0</version> <!-- 使用最新稳定版本 -->
</dependency>

2. 完整代码实现

import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Object;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class S3DirectoryCompressor {
    // 替换为你的存储桶名称
    private static final String BUCKET_NAME = "your-bucket-name";
    // 要压缩的目标前缀
    private static final String TARGET_PREFIX = "Demo/";
    // 压缩包在S3中的存储路径
    private static final String ZIP_OBJECT_KEY = "Demo/demo_all_files.zip";

    public static void main(String[] args) {
        // 初始化S3客户端(默认会读取本地AWS配置,或可自定义配置)
        try (S3Client s3Client = S3Client.create()) {
            // 1. 列出Demo/下的所有对象键
            List<String> objectKeys = listAllObjectsUnderPrefix(s3Client, BUCKET_NAME, TARGET_PREFIX);
            
            // 2. 下载对象并生成本地临时ZIP文件
            File tempZipFile = generateZipFromS3Objects(s3Client, BUCKET_NAME, objectKeys);
            
            // 3. 将ZIP文件上传回S3
            uploadZipToS3(s3Client, BUCKET_NAME, ZIP_OBJECT_KEY, tempZipFile);
            
            // 清理临时文件
            if (!tempZipFile.delete()) {
                System.err.println("警告:临时压缩文件删除失败,请手动清理");
            }

            System.out.println("压缩完成,压缩包已保存至S3:" + ZIP_OBJECT_KEY);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 列出指定前缀下的所有对象键
    private static List<String> listAllObjectsUnderPrefix(S3Client s3Client, String bucketName, String prefix) {
        List<String> objectKeys = new ArrayList<>();
        ListObjectsV2Request request = ListObjectsV2Request.builder()
                .bucket(bucketName)
                .prefix(prefix)
                .build();

        ListObjectsV2Response response;
        do {
            response = s3Client.listObjectsV2(request);
            for (S3Object obj : response.contents()) {
                objectKeys.add(obj.key());
            }
            // 处理分页,获取下一批对象
            request = request.toBuilder().continuationToken(response.nextContinuationToken()).build();
        } while (response.isTruncated());

        return objectKeys;
    }

    // 下载S3对象并打包成ZIP
    private static File generateZipFromS3Objects(S3Client s3Client, String bucketName, List<String> objectKeys) throws IOException {
        // 创建临时文件存储ZIP内容
        File tempZip = File.createTempFile("s3-demo-zip-", ".zip");

        try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(tempZip))) {
            for (String key : objectKeys) {
                // 从S3获取对象输入流
                try (InputStream objInputStream = s3Client.getObject(b -> b.bucket(bucketName).key(key))) {
                    // 设置ZIP内的文件名称(去掉前缀,避免压缩包内嵌套Demo目录)
                    String entryName = key.substring(TARGET_PREFIX.length());
                    ZipEntry entry = new ZipEntry(entryName);
                    zipOut.putNextEntry(entry);

                    // 读取S3对象内容并写入ZIP
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = objInputStream.read(buffer)) != -1) {
                        zipOut.write(buffer, 0, bytesRead);
                    }
                    zipOut.closeEntry();
                }
            }
        }
        return tempZip;
    }

    // 将ZIP文件上传至S3
    private static void uploadZipToS3(S3Client s3Client, String bucketName, String zipKey, File zipFile) throws IOException {
        PutObjectRequest putRequest = PutObjectRequest.builder()
                .bucket(bucketName)
                .key(zipKey)
                .build();

        s3Client.putObject(putRequest, zipFile.toPath());
    }
}

3. 关键注意事项

  • 权限配置:确保你的S3客户端拥有s3:ListBucket(列出对象)、s3:GetObject(下载对象)、s3:PutObject(上传压缩包)的权限。
  • 资源占用:如果文件总体积较大,建议监控磁盘空间;也可以改用内存流,但大文件场景下磁盘临时文件更稳定。
  • 分页处理:代码中已经处理了S3列表的分页逻辑,即使对象数量超过1000个也能完整获取。
  • 替代方案:如果不想在本地处理,可以编写Java Lambda函数,在云端完成下载、压缩、上传流程,避免占用本地资源,但需要配置Lambda的S3权限和触发条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 07:28:21