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

使用Java AWS Lambda将S3文件下载至本地的实现方案

可行方案说明

Lambda是无服务器执行环境,无法直接主动将文件传输到你的本地电脑,需要通过间接中转的方式实现,以下是两种实用方案:

方案1:通过API Gateway返回文件内容,本地发起HTTP请求下载

修改Lambda代码,将/tmp目录下的文件读取为字节流,通过API Gateway返回给本地客户端:

  1. 调整Lambda的返回类型,适配API Gateway的响应格式
  2. 在API Gateway控制台配置支持对应文件的二进制媒体类型(如application/pdf、image/jpeg等)
  3. 本地用curl、Postman或自定义脚本发起请求,将响应内容保存为本地文件

修改后的核心代码示例:

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import software.amazon.awssdk.services.s3.transfer.S3TransferManager;
import software.amazon.awssdk.services.s3.transfer.DownloadFileRequest;
import software.amazon.awssdk.services.s3.transfer.FileDownload;
import software.amazon.awssdk.services.s3.transfer.CompletedFileDownload;
import software.amazon.awssdk.transfer.s3.LoggingTransferListener;

public class S3DownloadHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {

    @Override
    public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
        String bucketName = "your-target-bucket";
        String key = "your-file-key";
        String downloadedFileWithPath = "/tmp/downloaded-file";
        
        // 原有下载到/tmp的逻辑
        S3TransferManager transferManager = S3TransferManager.create();
        DownloadFileRequest downloadFileRequest = DownloadFileRequest.builder()
                .getObjectRequest(b -> b.bucket(bucketName).key(key))
                .addTransferListener(LoggingTransferListener.create())
                .destination(Paths.get(downloadedFileWithPath))
                .build();

        FileDownload downloadFile = transferManager.downloadFile(downloadFileRequest);
        CompletedFileDownload downloadResult = downloadFile.completionFuture().join();
        
        // 读取文件并构造API响应
        APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
        try {
            byte[] fileBytes = Files.readAllBytes(Paths.get(downloadedFileWithPath));
            response.setStatusCode(200);
            response.setIsBase64Encoded(true);
            response.setBody(Base64.getEncoder().encodeToString(fileBytes));
            // 设置文件类型和下载文件名
            response.getHeaders().put("Content-Type", "application/octet-stream");
            response.getHeaders().put("Content-Disposition", "attachment; filename=\"local-saved-file\"");
        } catch (Exception e) {
            response.setStatusCode(500);
            response.setBody("文件读取失败: " + e.getMessage());
        }
        return response;
    }
}

本地下载命令示例(curl):

curl -X GET "https://your-api-gateway-endpoint/your-path" -o local-file-name

方案2:生成S3预签名URL,本地通过URL下载

如果文件较大(超过API Gateway默认10MB限制),优先用此方案:

  1. 将/tmp中的文件上传到一个临时S3位置(可复用原桶或单独的临时桶)
  2. 生成该文件的预签名URL(自定义有效期,比如1小时)
  3. Lambda返回这个URL,本地通过浏览器或curl访问URL完成下载

核心代码示例:

// 原有下载到/tmp的逻辑省略...

// 上传/tmp文件到临时S3路径
String tempBucket = "your-temp-bucket";
String tempKey = "temp/downloads/" + System.currentTimeMillis() + "-file";
UploadFileRequest uploadRequest = UploadFileRequest.builder()
        .putObjectRequest(b -> b.bucket(tempBucket).key(tempKey))
        .source(Paths.get(downloadedFileWithPath))
        .build();
CompletedFileUpload uploadResult = transferManager.uploadFile(uploadRequest).completionFuture().join();

// 生成1小时有效期的预签名URL
GetObjectRequest getObjectRequest = GetObjectRequest.builder()
        .bucket(tempBucket)
        .key(tempKey)
        .build();
PresignedGetObjectRequest presignedRequest = transferManager.presignGetObject(getObjectRequest, Duration.ofHours(1));

// 返回预签名URL(适配API Gateway的话直接返回字符串即可)
return presignedRequest.url().toString();

本地下载命令示例:

curl -X GET "https://your-temp-bucket.s3.your-region.amazonaws.com/temp/downloads/123456789-file" -o local-file-name

注意事项

  • Lambda的/tmp目录默认最大存储512MB,超大文件无法下载到该目录
  • 预签名URL的有效期不要设置过长,避免未授权访问风险
  • 若用方案1,需确保API Gateway的payload限制能覆盖文件大小

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:57:29