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

访问S3存储桶时遭遇java.io.FileNotFoundException问题求助

兄弟,我之前做Lambda处理S3文件的时候也踩过这个java.io.FileNotFoundException的坑,大概率是这几个原因导致的,给你一步步排查:

1. 错误地用本地文件路径访问S3对象

S3的存储对象并不是Lambda执行环境本地文件系统里的文件,你要是直接用new File(objectKey)这种方式去访问,肯定会报找不到文件的错误。正确的姿势是用AWS SDK的S3客户端获取对象的输入流来读取内容。

2. Lambda执行角色缺少S3读取权限

如果你的Lambda角色没有s3:GetObject权限,就算路径对了也读不到S3文件。需要给Lambda的IAM角色添加如下策略(记得替换成你的桶名):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your-bucket-name/*"
        }
    ]
}

3. S3对象键的URL编码问题

S3事件里返回的对象键可能是URL编码后的(比如空格会变成%20),如果直接用这个编码后的键去调用getObject,会找不到对应的对象。你需要先解码:

import java.net.URLDecoder;
// ...
String encodedKey = s3event.getRecords().get(0).getS3().getObject().getKey();
String objectKey = URLDecoder.decode(encodedKey, "UTF-8");

4. S3桶区域与Lambda客户端区域不匹配

你代码里硬编码了US_EAST_1区域,但如果你的S3桶在其他区域(比如US_WEST_2),客户端和桶区域不匹配也会导致访问失败。建议不要硬编码区域,用默认客户端会自动匹配Lambda执行环境的区域:

private final AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient();

给你一个修正后的代码示例

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.S3Event;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.S3Object;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URLDecoder;

public class LambdaFunctionHandler implements RequestHandler<S3Event, Report> {

    // 使用默认客户端,自动匹配区域
    private final AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient();

    public Report handleRequest(S3Event s3event, Context context) {
        long startTime = System.currentTimeMillis();
        Report statusReport = new Report();
        
        try {
            // 从S3事件中获取桶名和编码后的对象键
            String bucketName = s3event.getRecords().get(0).getS3().getBucket().getName();
            String encodedObjectKey = s3event.getRecords().get(0).getS3().getObject().getKey();
            
            // 解码对象键,处理特殊字符
            String objectKey = URLDecoder.decode(encodedObjectKey, "UTF-8");
            
            // 通过S3客户端获取对象输入流
            S3Object s3Object = s3Client.getObject(bucketName, objectKey);
            
            // 读取CSV内容并输出到CloudWatch日志
            BufferedReader reader = new BufferedReader(new InputStreamReader(s3Object.getObjectContent()));
            String line;
            while ((line = reader.readLine()) != null) {
                context.getLogger().log("CSV line: " + line);
            }
            
            statusReport.setSuccess(true);
            statusReport.setMessage("File read successfully");
        } catch (IOException e) {
            context.getLogger().log("Error reading file: " + e.getMessage());
            statusReport.setSuccess(false);
            statusReport.setMessage(e.getMessage());
        }
        
        long endTime = System.currentTimeMillis();
        statusReport.setProcessingTime(endTime - startTime);
        return statusReport;
    }
}

最后再提醒下:测试的时候可以手动构造S3事件触发Lambda,或者确保S3桶的事件通知配置正确,把触发条件设为你需要的文件上传事件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:00:31