【问题标题】:Python: create a file on S3Python:在 S3 上创建一个文件
【发布时间】:2023-01-16 13:36:15
【问题描述】:

我在下面有一个函数用于生成一个巨大的文本文件的行。

def generate_content(n):
    for _ in range(n):
        yield 'xxx'

不是将文件保存到磁盘,然后将其上传到 S3,有没有办法将数据直接保存到 S3?

需要提及的一件事是数据可能非常庞大,以至于我没有足够的磁盘空间或内存来容纳它。

【问题讨论】:

  • 您是在问是否可以将转换的某些部分上传到 S3,最后将所有这些小文件聚合到一个大文件中?如果你没有足够的内存,你打算怎么读呢?

标签: python amazon-web-services file amazon-s3 upload


【解决方案1】:

boto3 需要一个文件、一个字节数组或一个类似对象的文件来将对象上传到 S3。其中,您可以合理使用的唯一一个不需要内存或磁盘上对象的全部内容的文件类对象,使用自定义文件对象帮助器来满足读取请求。

基本上,您可以调用您的生成器来满足对read() 的请求,boto3 将负责为您创建对象:

import boto3

def generate_content(n):
    for i in range(n):
        yield 'xxx'

# Convert a generator that returns a series of strings into 
# a object that implements 'read()' in a method similar to how
# a file object operates.
class GenToBytes:
    def __init__(self, generator):
        self._generator = generator
        self._buffers = []
        self._bytes_avail = 0
        self._at_end = False

    # Emulate a file object's read    
    def read(self, to_read=1048576):
        # Call the generate to read enough data to satisfy the read request
        while not self._at_end and self._bytes_avail < to_read:
            try:
                row = next(self._generator).encode("utf-8")
                self._bytes_avail += len(row)
                self._buffers.append(row)
            except StopIteration:
                # We're all done reading
                self._at_end = True
        if len(self._buffers) > 1:
            # We have more than one pending buffer, concat them together
            self._buffers = [b''.join(self._buffers)]
        # Pull out the requested data, and store the rest
        ret, self._buffers = self._buffers[0][:to_read], [self._buffers[0][to_read:]]
        self._bytes_avail -= len(ret)
        return ret

s3 = boto3.client('s3')
generator = generate_content(100) #Generate 100 rows
s3.upload_fileobj(GenToBytes(generator), bucket, key)

【讨论】:

    猜你喜欢
    • 2019-11-12
    • 2021-04-05
    • 2016-12-02
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多