AWS Lambda中java.io.FileNotFoundException(只读文件系统)问题咨询
解决AWS Lambda中Spring Boot应用文件写入与S3上传问题
问题1:Lambda只读文件系统导致写入失败
原代码
file = new File(fileName);// fileName is just a String.txt context.getLogger().log("File Path1: "+file.getAbsolutePath()); FileUtils.writeLines(file, failedMessages); //failedMessages is a List<String> context.getLogger().log("File Path2: "+file.getAbsolutePath());
错误日志
File Path1: /var/task/Platform_Status_Failed_2022_09_09.txt Exception caught java.io.FileNotFoundException: Platform_Status_Failed_2022_09_09.txt (Read-only file system)
修复方案
AWS Lambda的/var/task目录是只读的,仅/tmp目录支持文件写入。必须将文件路径改为/tmp/前缀:
String tmpFilePath = "/tmp/" + fileName; File file = new File(tmpFilePath); context.getLogger().log("File Path1: "+file.getAbsolutePath()); FileUtils.writeLines(file, failedMessages); context.getLogger().log("File Path2: "+file.getAbsolutePath());
问题2:使用/tmp后上传S3找不到文件的异常
错误日志
Unable to calculate MD5 hash: /tmp/Platform_Status_Failed_2022_09_09.txt (No such file or directory): java.lang.BootstrapMethodError java.lang.BootstrapMethodError: Unable to calculate MD5 hash: /tmp/Platform_Status_Failed_2022_09_09.txt (No such file or directory) at com.paytmmoney.bo.equities.lambda.handler.LambdaMethodHandler.uploadToS3(LambdaMethodHandler.java:171) at com.paytmmoney.bo.equities.lambda.handler.LambdaMethodHandler.uploadFileToS3(LambdaMethodHandler.java:88) at com.paytmmoney.bo.equities.lambda.handler.LambdaMethodHandler.handleRequest(LambdaMethodHandler.java:58) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) Caused by: com.amazonaws.SdkClientException: Unable to calculate MD5 hash: /tmp/Platform_Status_Failed_2022_09_09.txt (No such file or directory) at com.amazonaws.services.s3.AmazonS3Client.getInputStream(AmazonS3Client.java:1849) at com.amazonaws.services.s3.AmazonS3Client.uploadObject(AmazonS3Client.java:1767) at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1746) at com.paytmmoney.bo.equities.lambda.handler.LambdaMethodHandler.uploadToS3(LambdaMethodHandler.java:159) ... 6 more Caused by: java.io.FileNotFoundException: /tmp/Platform_Status_Failed_2022_09_09.txt (No such file or directory) at java.io.FileInputStream.open0(Native Method) at java.io.FileInputStream.open(FileInputStream.java:195) at java.io.FileInputStream.<init>(FileInputStream.java:138) at com.amazonaws.util.Md5Utils.computeMD5Hash(Md5Utils.java:97) at com.amazonaws.util.Md5Utils.md5AsBase64(Md5Utils.java:104) at com.amazonaws.services.s3.AmazonS3Client.getInputStream(AmazonS3Client.java:1845) ... 9 more
可能原因及修复方案
文件写入未完成或路径错误
确保写入时使用完整绝对路径,并验证文件是否存在:String tmpFilePath = "/tmp/" + fileName; File file = new File(tmpFilePath); try { FileUtils.writeLines(file, failedMessages); // 写入后验证文件状态 if (file.exists() && file.length() > 0) { context.getLogger().log("文件写入成功:" + tmpFilePath); } else { throw new RuntimeException("文件写入后为空或不存在"); } } catch (IOException e) { context.getLogger().log("写入文件失败:" + e.getMessage()); throw new RuntimeException("文件写入失败", e); }上传路径拼写错误
确认S3上传代码中使用的路径与写入路径完全一致,不要遗漏/tmp/前缀或拼写错误。绕过文件写入,直接用内存流上传
若无需持久化文件,建议直接通过内存流上传到S3,避免磁盘IO问题:import java.nio.charset.StandardCharsets; import java.io.ByteArrayInputStream; import com.amazonaws.services.s3.model.PutObjectRequest; import com.amazonaws.services.s3.model.ObjectMetadata; // 将List<String>转为字节流 String content = String.join(System.lineSeparator(), failedMessages); byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8); ByteArrayInputStream inputStream = new ByteArrayInputStream(contentBytes); // 上传到S3 ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(contentBytes.length); PutObjectRequest request = new PutObjectRequest("your-bucket-name", "s3-file-key", inputStream, metadata); amazonS3.putObject(request);
内容的提问来源于stack exchange,提问作者Aditya K
相关产品推荐
相关产品推荐

