使用boto3处理S3中CSV转JSON时触发FileNotFoundError报错
解决S3 CSV转JSON时的FileNotFoundError问题
问题场景
在S3存储桶中存有一个1KB的CSV文件,使用boto3可以正常打印存储桶名称、文件key以及文件内容,但在将其转换为JSON格式时,触发「No file found」报错。具体情况:
- S3中确实存在目标CSV文件
- 可正常打印bucket名称、key和文件内容
- 仅存在这一个1KB的CSV文件
- 转换JSON阶段触发文件未找到错误
原出错代码
import boto3 import csv import json # set up S3 connection s3 = boto3.resource('s3') my_bucket = s3.Bucket('csvfolder3') # bucket_name = 'csvfolder3' def lambda_handler(event, context): for file in my_bucket.objects.all(): print(file.key) body = file.get()['Body'].read() print(body) with open(file.key, 'r') as csvfile: #####[ERROR] FileNotFoundError: [Errno 2] No such file or directory: 'data.csv' data = [row for row in csv.DictReader(csvfile)] json_data = json.dumps(data) s3.Object(my_bucket, 'file.json').put(Body=json_data)
错误原因
open(file.key, 'r')这行代码是尝试读取本地文件系统中的文件,但你只是从S3获取了文件内容的二进制数据,并没有把数据保存到本地路径下,所以用file.key作为本地路径自然找不到文件。Lambda环境的临时存储虽然可以写入,但完全没必要做本地文件IO,直接在内存中处理即可。
修正后的代码
import boto3 import csv import json import io # 设置S3连接 s3 = boto3.resource('s3') bucket_name = 'csvfolder3' my_bucket = s3.Bucket(bucket_name) def lambda_handler(event, context): for file in my_bucket.objects.all(): print(file.key) # 读取S3文件二进制内容并转成UTF-8字符串 body_str = file.get()['Body'].read().decode('utf-8') print(body_str) # 用StringIO在内存中模拟文件对象,供csv.DictReader读取 with io.StringIO(body_str) as csvfile: data = [row for row in csv.DictReader(csvfile)] json_data = json.dumps(data, ensure_ascii=False) # 写入JSON到S3,注意第一个参数传桶名字符串 s3.Object(bucket_name, 'file.json').put(Body=json_data.encode('utf-8'))
关键修正点
- 使用
io.StringIO将从S3读取的字符串包装成类文件对象,完全在内存中处理,避免本地文件操作 - 把S3返回的二进制
Body用decode('utf-8')转换成字符串(如果CSV是其他编码,比如GBK,替换对应编码即可) - 修正
S3.Object()的参数:第一个参数需要传入桶名字符串,不能直接传Bucket对象 - 转JSON时添加
ensure_ascii=False,避免中文等非ASCII字符被转义,写入时再用encode('utf-8')转回二进制确保兼容性
内容的提问来源于stack exchange,提问作者sim
相关产品推荐
相关产品推荐

