Java编写AWS Lambda配合S3事件生成PDF出现只读文件系统错误求助
问题解决方法
错误根因
AWS Lambda运行环境的文件系统仅/tmp目录开放读写权限,其余目录均为只读状态。你的代码直接在默认工作目录创建FileCreated.pdf文件,触发了只读文件系统限制,因此抛出文件不存在异常。
修复方案
方案1:将临时文件写入/tmp目录(改动最小)
仅需要修改代码中两处文件路径,同时修正错误的文件元数据配置即可:
- 创建PDF输出流时指定路径为
/tmp/FileCreated.pdf - 读取文件上传到S3时使用相同的
/tmp路径 - 将Content-Type从
plain/text改为PDF对应的application/pdf
修改后的核心代码片段如下:
//PDF Create Document document = new Document(PageSize.A4, 50, 50, 50, 50); // 改路径到/tmp目录 PdfWriter.getInstance(document, new FileOutputStream("/tmp/FileCreated.pdf")); document.open(); document.add(new Paragraph("Data test")); // 后续可以替换为读取的CSV内容 document.close(); PutObjectRequest request = new PutObjectRequest(bucket, nameOfTheNewFile, new File("/tmp/FileCreated.pdf")); ObjectMetadata metadata = new ObjectMetadata(); // 修正Content-Type为PDF类型 metadata.setContentType("application/pdf"); metadata.addUserMetadata("title", "someTitle"); request.setMetadata(metadata); s3Client.putObject(request);
方案2:使用内存流避免写本地文件(性能更优)
如果生成的PDF体积较小,建议直接将PDF写入字节数组流,完全跳过本地文件写入步骤,既避免文件系统限制,也能提升执行效率:
//PDF Create 写入内存流 Document document = new Document(PageSize.A4, 50, 50, 50, 50); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); PdfWriter.getInstance(document, outputStream); document.open(); document.add(new Paragraph("Data test")); document.close(); byte[] pdfBytes = outputStream.toByteArray(); // 直接上传字节数组 ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType("application/pdf"); metadata.setContentLength(pdfBytes.length); metadata.addUserMetadata("title", "someTitle"); s3Client.putObject(bucket, nameOfTheNewFile, new ByteArrayInputStream(pdfBytes), metadata);
额外注意事项
- Lambda的
/tmp目录最大可用空间为512MB,若生成的PDF超过该大小必须使用流式上传方案 - 需要确认Lambda的执行角色已经配置了目标S3存储桶的
s3:PutObject权限,否则会出现权限不足导致的上传失败 - 当前代码中生成的PDF文件名固定为
newFileObjKeyName.pdf,多次触发会覆盖旧文件,建议关联上传的CSV文件名生成,比如将原CSV文件的.csv后缀替换为.pdf,避免覆盖问题
内容的提问来源于stack exchange,提问作者Zekitui
相关产品推荐
相关产品推荐

