当前位置: 首页 > 面试题库 >

使用boto3和回调跟踪S3文件的下载进度

徐奇逸
2023-03-14
问题内容

我正在尝试使用boto3从S3下载文本文件。

这是我写的。

class ProgressPercentage(object):
    def __init__(self, filename):
        self._filename = filename
        self._size = float(os.path.getsize(filename))
        self._seen_so_far = 0
        self._lock = threading.Lock()

    def __call__(self, bytes_amount):
        # To simplify we'll assume this is hooked up
        # to a single filename.
        with self._lock:
            self._seen_so_far += bytes_amount
            percentage = round((self._seen_so_far / self._size) * 100,2)
            LoggingFile('{} is the file name. {} out of {} done. The percentage completed is {} %'.format(str(self._filename), str(self._seen_so_far), str(self._size),str(percentage)))
            sys.stdout.flush()

我用它来称呼它

transfer.download_file(BUCKET_NAME,FILE_NAME,'{}{}'.format(LOCAL_PATH_TEMP , FILE_NAME),callback = ProgressPercentage(LOCAL_PATH_TEMP + FILE_NAME))

这给我一个错误,指出该文件夹中没有该文件。显然,当我已经在同一文件夹中拥有此名称的文件时,它可以工作,但是当我下载新文件时,它会出错。

我需要进行什么纠正?


问题答案:

callback = ProgressPercentage(LOCAL_PATH_TEMP + FILE_NAME))创建一个ProgressPercentage对象,运行其__init__方法,然后将该对象传递callback给该download_file方法。这意味着该__init__方法
download_file开始 之前 运行。

在该__init__方法中,您尝试读取要下载到的本地文件的大小,这将引发异常,因为该文件不存在,因为下载尚未开始。如果您已经下载了文件,那么没有问题,因为存在本地副本并且可以读取其大小。

当然,这仅仅是您所看到的异常的原因。您正在使用该_size属性作为下载进度的最大值。但是,您尝试使用本地文件的大小。在文件完全下载之前,本地文件系统不知道文件有多大,它仅知道当前占用了多少空间。这意味着在您下载文件时,文件将逐渐变大,直到达到其完整大小。因此,将本地文件的大小视为下载的最大大小并没有任何意义。在您已经下载文件的情况下,它可能会起作用,但这不是很有用。

解决问题的方法是检查要下载的文件的大小,而不是本地副本的大小。这样可以确保您获得要下载的文件的实际大小,并且该文件存在(因为如果不下载,则无法下载)。您可以通过获取远程文件的大小与做head_object如下

class ProgressPercentage(object):
    def __init__(self, client, bucket, filename):
        # ... everything else the same
        self._size = client.head_object(Bucket=bucket, Key=filename).ContentLength

    # ...

# If you still have the client object you could pass that directly 
# instead of transfer._manager._client
progress = ProgressPercentage(transfer._manager._client, BUCKET_NAME, FILE_NAME)
transfer.download_file(..., callback=progress)

最后一点,尽管您从Boto3文档中获得了代码,但该代码不起作用,因为它是用于文件上传的。在这种情况下,本地文件是源文件并保证其存在。



 类似资料:
  • 问题内容: 我们正在使用Amazon AWS Java库上载文件,并且很难获得上载进度。我们目前正在致电以下内容: 我们如何设置回调以检查文件上传进度? 谢谢 问题答案: 我遇到了这个确切的问题,并编写了一个简单的InputStream包装器,该包装器输出了不错的进度条: (这是从实时代码中复制粘贴的,因此您可能必须做一些修补才能使其在您自己的代码中起作用。) 然后,只需使用InputStream

  • 问题内容: 我编写了一个程序来列出命令执行的所有系统调用(例如/ bin / ls)。现在我想做的就是找到所有可能传递给它的系统调用参数,环境变量,命令行参数 示例:如果我打开一个文件。系统调用sys_access会打开文件吗?但是如何获得这些价值? 想要对系统调用(例如打开,读取,写入,关闭)执行此操作。 根据我的研究,这些必须在寄存器(ebx- edx)中。如果是,则这些寄存器值表示什么?我知

  • 我正在LinuxAcademy网站上做一个实验室。com课程名称是使用Lambda、Python和Boto3自动化自动气象站,我遇到问题的具体实验室是讲座:将CSV文件导入DynamoDB。 在这个实验室中,我们将一个. csv文件上传到S3,在该特定桶中生成一个S3事件,然后启动如下所示的Lambda脚本: 上传到s3的.csv文件确实调用了lambda函数。第20行出现错误: AWS Clou

  • 运行上述代码后出现以下错误。请帮忙做这件事。。正在将源和目标文件名作为S3属性中的参数传递。。。 在处理上述异常时,发生了另一个异常: 回溯(最后一次调用):文件“C:\Cloudtail\CT\SQL Scripts\python\GRN\u S3\u dwnld.py”,第17行,除了botocore.exception.ClientErrors as e:NameError:未定义名称“bo

  • 我已使用IAM角色启动了一个ec2实例,并将以下策略与IAM角色关联。 然而,当我试图从ec2-实例中使用aws cli下载文件时,我一直拒绝访问。 当我模拟策略并对bucket中的对象执行操作时,会收到消息“allowed”。当我访问时,我可以看到正确的实例配置文件附在实例上http://169.254.254/latest-metadata/iam/info 我有什么明显的遗漏吗?

  • 根据AWS文档中提供的资源,可以通过以下代码下载对象: 编辑 我将更改为,它打开了pdf,但现在我需要下载它