2016-09-19 124 views
3

背景IO错误download_file

我使用boto3代码从s3.Here下载文件是下面的代码。

for record in event['Records']: 
    bucket = record['s3']['bucket']['name'] 
    key = record['s3']['object']['key'] 
    print (key) 
    if key.find('/') < 0 : 
    if len(key) > 4 and key[-5:].lower() == '.json': //File is uploaded outside any folder 

     download_path = '/tmp/{}{}'.format(uuid.uuid4(), key) 
    else: 
     download_path = '/tmp/{}/{}'.format(uuid.uuid4(), key)//File is uploaded inside a folder 

如果一个新的文件在S3存储桶上传的,这段代码被触发,以及在新上传的文件是由该代码下载。

此代码工作正常,当上传任何文件夹之外。

但是,当我上传目录中的文件,发生IO错误。 这是我遇到的IO错误的转储。

[错误2]没有这样的文件或目录: /tmp/316bbe85-fa21-463b-b965-9c12b0327f5d/test1/customer1.json.586ea9b8: 的IOError

TEST1是我的s3存储桶中的目录,其中上传customer1.json。

查询

任何思考,如何解决这个问题?

回答

2

由于您试图将文件下载并保存到不存在的目录中而引发错误。在使用os.mkdir下载文件之前创建一个目录。

# ... 
else: 
    item_uuid = str(uuid.uuid4()) 
    os.mkdir('/tmp/{}'.format(item_uuid)) 
    download_path = '/tmp/{}/{}'.format(item_uuid, key) # File is uploaded inside a folder 

注意:这是更好地使用os.path.join()同时用系统的路径运行。所以,上面的代码可以被改写为:

# ... 
else: 
    item_uuid = str(uuid.uuid4()) 
    os.mkdir(os.path.join(['tmp', item_uuid])) 
    download_path = os.path.join(['tmp', item_uuid, key])) 

而且错误可能是引发,因为你包括在S3存储桶文件下载路径“的/ tmp /”,不包括tmp文件夹可能它不存在于S3。确保你在正确的方式通过使用物品:

+1

确定,但即使尝试了这一点,同样的错误后仍继续[错误2]没有这样的文件或目录。/tmp/316bbe85-fa21-463b-b965-9c12b0327f5d/test1/customer1.json.586ea9b8:IO错误...............................................我打印我的download_path,它给出了“/tmp/316bbe85-fa21-463b-b965-9c12b0327f5d”,键给出为“test1/customer1.json”,但是在错误中我看到一个额外的“.586ea9b8”追加......这是否导致了错误现在...如果是,我们如何消除这一点。 – Rohan

+0

@Rohan查看更新答案。 –

+0

我想它的权利,但在我的情况下,文件夹已成功创建,但是当s3.download_file被调用时,它会抛出错误[Errno 2]没有这样的文件或目录:/ tmp/316bbe85-fa21-463b-b965- 9c12b0327f5d/TEST1/customer1.js on.586ea9b8。 – Rohan

0

感谢帮助舍甫琴科Ivaneyko,我发现使用boto3的解决方案。

使用下面的代码我能够完成我的任务。

for record in event['Records']: 
    bucket = record['s3']['bucket']['name'] 
    key = record['s3']['object']['key'] 
    fn='/tmp/xyz' 
    fp=open(fn,'w') 
    response = s3_client.get_object(Bucket=bucket,Key=key) 
    contents = response['Body'].read() 
    fp.write(contents) 
    fp.close()