从S3下载文件时,在AWS Lambda中出现“只读文件系统”错误

130

当我将一个file.csv文件放入S3存储桶时,我的lambda函数出现以下错误。这个文件并不大,我甚至在读取文件之前添加了60秒的休眠时间,但是出现了额外的".6CEdFe7C"附加到文件上的情况。为什么会这样?

[Errno 30] Read-only file system: u'/file.csv.6CEdFe7C': IOError
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 75, in lambda_handler
s3.download_file(bucket, key, filepath)
File "/var/runtime/boto3/s3/inject.py", line 104, in download_file
extra_args=ExtraArgs, callback=Callback)
File "/var/runtime/boto3/s3/transfer.py", line 670, in download_file
extra_args, callback)
File "/var/runtime/boto3/s3/transfer.py", line 685, in _download_file
self._get_object(bucket, key, filename, extra_args, callback)
File "/var/runtime/boto3/s3/transfer.py", line 709, in _get_object
extra_args, callback)
File "/var/runtime/boto3/s3/transfer.py", line 723, in _do_get_object
with self._osutil.open(filename, 'wb') as f:
File "/var/runtime/boto3/s3/transfer.py", line 332, in open
return open(filename, mode)
IOError: [Errno 30] Read-only file system: u'/file.csv.6CEdFe7C'

代码:

def lambda_handler(event, context):

    s3_response = {}
    counter = 0
    event_records = event.get("Records", [])

    s3_items = []
    for event_record in event_records:
        if "s3" in event_record:
            bucket = event_record["s3"]["bucket"]["name"]
            key = event_record["s3"]["object"]["key"]
            filepath = '/' + key
            print(bucket)
            print(key)
            print(filepath)
            s3.download_file(bucket, key, filepath)

以上的结果是:

mytestbucket
file.csv
/file.csv
[Errno 30] Read-only file system: u'/file.csv.6CEdFe7C'

如果密钥/文件名为"file.csv",那么为什么s3.download_file方法要尝试下载"file.csv.6CEdFe7C"?我猜测当函数被触发时,文件是file.csv.xxxxx,但到达第75行时,文件被重命名为file.csv了吗?


转储不等于读取!因此,您在临时文件夹(或RAM中)的文件需要进行转储,而不是使用self._osutil.open(filename, 'wb') as f:。只允许使用rb等模式。因此,在处理之前需要处理源文件。 - dsgdfg
@user1530318,您介意将最佳答案标记为正确吗?看起来没问题。 - Nikolai K.
4个回答

359

34
一个半小时后,我找到了你的答案... 为什么他们不明确说明呢?谢谢! - ProgrammingLlama
4
我也曾经有同样的疑问,甚至在谷歌上搜索原因都很困难!很高兴我能帮到你,伙计。 - joonas.fi
2
@john AWS的文档非常庞大,这是一个问题! - Ivan Aracki
在我的类似情况下(将“File”写入user.dir:“/<filename>”),但使用JAVA和一个3.8MB的.zip对象,这个警告在我的["只读"]SDKClientException之前打印出来(但在使用/tmp/解决方案后,它被愉快地解决了!可能是因为S3ObjectInputStream在无法获取先前的“/<filename>”时立即停止工作):“警告:未从S3ObjectInputStream中读取所有字节,中止HTTP连接。这很可能是一个错误,并可能导致次优行为。通过分段GET请求仅请求所需的字节或在使用后排空输入流。” - cellepo
1
感谢,将验证'/tmp'。 - Himanshu dua
显示剩余6条评论

22

1
很酷,那是你的代码,有什么问题吗?如果你的答案解决了问题,请加上解释为什么它有效。如果不行,请删除它。 - sjaustirni
已更正,请告知是否需要设置更多信息。 - Egalicia
5
即使只是一个示例,请不要将代码放在图像中。请在此过程中修复您回答中的拼写错误。总体而言,回答变得更好了。 :-D - sjaustirni

1
我注意到,当我上传一个直接压缩为zip文件的lambda代码时,我只能写入/tmp文件夹,但是当我从S3上传代码时,我可以同时写入项目根目录文件夹。

1
你有例子吗? - annedroiid

0

对于C#也完美运行:

using (var fileStream = File.Create("/tmp/" + fName))
{
   str.Seek(0, SeekOrigin.Begin);
   str.CopyTo(fileStream);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接