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

时间:2018-08-01 11:33:50

标签: python ftp sftp paramiko ftplib

我需要能够在Python中通过FTP和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中需要此文件,但对于SFTP在Paramiko中也将需要它。如果还有其他更好的库,我会开放。

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

1 个答案:

答案 0 :(得分:0)

您可以实现类似文件的类,该类在调用.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一起使用。