繁体   English   中英

Python:在S3上创建一个文件

[英]Python: create a file on S3

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

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

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

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

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

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

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM