Python - 在 FTP 中按块上传内存中文件(由 API 调用生成)

Python - Upload a in-memory file (generated by API calls) in FTP by chunks

我需要能够通过 FTP 和 Python 中的 SFTP 上传文件,但有一些不常见的限制。

  1. 文件不得写入磁盘。

  2. 文件的生成方式是调用 API 并将 JSON 中的响应写入文件。

  3. API 有多个调用。不可能在 API 的一次调用中检索整个结果。

  4. 我无法通过执行所需的多次调用并在每次调用中追加,直到将整个文件存储在内存中,从而将完整结果存储在字符串变量中。文件可能很大并且存在内存资源限制。应发送每个块并释放内存。

所以这里有一些我想要的示例代码:

def chunks_generator():
    range_list = range(0, 4000, 100)
    for i in range_list:
        data_chunk = requests.get(url=someurl, url_parameters={'offset':i, 'limit':100})
        yield str(data_chunk)

def upload_file():
    chunks_generator = chunks_generator()
    for chunk in chunks_generator:
        data_chunk= chunk
        chunk_io = io.BytesIO(data_chunk)
        ftp = FTP(self.host)
        ftp.login(user=self.username, passwd=self.password)
        ftp.cwd(self.remote_path)
        ftp.storbinary("STOR " + "myfilename.json", chunk_io)

我只想要一个附加了所有块的文件。 我已经拥有并且可以工作的是,如果我将整个文件放在内存中并像这样立即发送它:

string_io = io.BytesIO(all_chunks_together_in_one_string)
ftp = FTP(self.host)
ftp.login(user=self.username, passwd=self.password)
ftp.cwd(self.remote_path)
ftp.storbinary("STOR " + "myfilename.json", string_io )

奖金

我在 ftplib 中需要它,但在 Paramiko 中也需要它用于 SFTP。如果有任何其他库可以更好地工作,我是开放的。

如果我需要压缩文件怎么办?我可以压缩每个块并一次发送压缩块吗?

您可以实现类文件 class,在调用 .read(blocksize) 方法时从 requests 对象检索数据。

像这样(未经测试):

class ChunksGenerator:
    i = 0
    requests = None

    def __init__(self, requests)
        self.requests = requests

    def read(self, blocksize):
        # TODO: somehow detect end-of-file and return false in that case
        buf = requests.get(
                  url=someurl, url_parameters={'offset':self.i, 'limit':blocksize})
        self.i += blocksize
        return buf

generator = ChunksGenerator(requests)
ftp.storbinary("STOR " + "myfilename.json", generator)

对于 Paramiko,您可以使用与 SFTPClient.putfo method 相同的 class。