【问题标题】:How do I download a file from S3 using boto only if the remote file is newer than a local copy?仅当远程文件比本地副本新时,如何使用 boto 从 S3 下载文件?
【发布时间】:2014-10-02 14:35:46
【问题描述】:

我正在尝试使用 boto 从 S3 下载文件,但前提是该文件的本地副本比远程文件旧。

我正在使用标题“If-Modified-Since”和下面的代码:

#!/usr/bin/python
import os
import datetime
import boto
from boto.s3.key import Key

bucket_name = 'my-bucket'

conn = boto.connect_s3()
bucket = conn.get_bucket(bucket_name)

def download(bucket, filename):
    key = Key(bucket, filename)
    headers = {}
    if os.path.isfile(filename):
        print "File exists, adding If-Modified-Since header"
        modified_since = os.path.getmtime(filename)
        timestamp = datetime.datetime.utcfromtimestamp(modified_since)
        headers['If-Modified-Since'] = timestamp.strftime("%a, %d %b %Y %H:%M:%S GMT")
    try:
        key.get_contents_to_filename(filename, headers)
    except boto.exception.S3ResponseError as e:
        return 304
    return 200

print download(bucket, 'README')

问题是当本地文件不存在时,一切正常并且文件被下载。当我第二次运行脚本时,我的函数按预期返回 304,但之前下载的文件被删除了。

【问题讨论】:

    标签: python amazon-s3 boto


    【解决方案1】:

    boto.s3.key.Key.get_contents_to_filenamewb 模式打开文件;它在函数的开头截断文件(boto/s3/key.py)。除此之外,它会在引发异常时删除文件。

    除了get_contents_to_filename,您可以使用get_contents_to_file 与不同的打开模式。

    def download(bucket, filename):
        key = Key(bucket, filename)
        headers = {}
        mode = 'wb'
        updating = False
        if os.path.isfile(filename):
            mode = 'r+b'
            updating = True
            print "File exists, adding If-Modified-Since header"
            modified_since = os.path.getmtime(filename)
            timestamp = datetime.datetime.utcfromtimestamp(modified_since)
            headers['If-Modified-Since'] = timestamp.strftime("%a, %d %b %Y %H:%M:%S GMT")
        try:
            with open(filename, mode) as f:
                key.get_contents_to_file(f, headers)
                f.truncate()
        except boto.exception.S3ResponseError as e:
            if not updating:
                # got an error and we are not updating an existing file
                # delete the file that was created due to mode = 'wb'
                os.remove(filename)
            return e.status
        return 200
    

    注意 file.truncate 用于处理新文件小于前一个文件的情况。

    【讨论】:

    • 附带说明,当 S3 响应 404 时,无论如何都会创建本地文件。
    猜你喜欢
    • 2020-01-03
    • 2016-09-23
    • 2012-10-24
    • 2020-08-15
    • 1970-01-01
    • 2012-10-15
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    相关资源
    最近更新 更多