如何在python中不使用临时fi在tarfile中写入大量数据

2024-10-01 17:32:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我用python编写了一个小的加密模块,其任务是加密一个文件并将结果放入tarfile中。要加密的原始文件可以非常大,但这不是问题,因为我的程序一次只需要处理一小部分数据,这些数据可以实时加密并存储。在

我正在寻找一种方法来避免在两个过程中执行此操作,首先将所有数据写入临时文件,然后将结果插入tarfile。在

基本上我做了以下工作(generator_uencryptor是一个简单的生成器,它生成从sourcefile读取的数据块)。 公司名称:

t = tarfile.open("target.tar", "w")
tmp = file('content', 'wb')
for chunk in generator_encryptor("sourcefile"):
   tmp.write(chunks)
tmp.close()
t.add(content)
t.close()

我有点恼火,我不得不使用一个临时文件,因为我不能保证我有足够的内存来旧bigcipheredstring,所以直接在tar文件中写入blocs应该很容易,但是在单个字符串中收集每个块并使用诸如t.addfile('content',StringIO(bigcipheredstring)似乎被排除在外了。在

有什么建议吗?在


Tags: 模块文件数据方法程序close过程tar
3条回答

基本上是使用类似文件的对象并将其传递给TarFile.addfile文件尽管如此,还是有一些问题有待解决。在

  • 我需要在开始时知道完整的加密文件大小
  • tarfile访问read方法的方式是,自定义的类文件对象必须始终返回完整的读取缓冲区,或者tarfile假设它是文件末尾。在read方法的代码中,这会导致一些非常低效的缓冲区复制,但要么就是这样,要么就是更改tarfile模块。在

结果代码如下,基本上我必须编写一个包装类,将现有的生成器转换为类似文件的对象。我还在示例中添加了GeneratorEncrypto类,以使代码完成。您可以注意到它有一个len方法,它返回所写文件的长度(但要知道它只是一个虚拟占位符,没有任何用处)。在

import tarfile

class GeneratorEncryptor(object):
    """Dummy class for testing purpose

       The real one perform on the fly encryption of source file
    """
    def __init__(self, source):
        self.source = source
        self.BLOCKSIZE = 1024
        self.NBBLOCKS = 1000

    def __call__(self):
        for c in range(0, self.NBBLOCKS):
            yield self.BLOCKSIZE * str(c%10)

    def __len__(self):
        return self.BLOCKSIZE * self.NBBLOCKS

class GeneratorToFile(object):
    """Transform a data generator into a conventional file handle
    """
    def __init__(self, generator):
        self.buf = ''
        self.generator = generator()

    def read(self, size):
        chunk = self.buf
        while len(chunk) < size:
            try:
                chunk = chunk + self.generator.next()
            except StopIteration:
                self.buf = ''
                return chunk
        self.buf = chunk[size:]
        return chunk[:size]

t = tarfile.open("target.tar", "w")
tmp = file('content', 'wb')
generator = GeneratorEncryptor("source")
ti = t.gettarinfo(name = "content")
ti.size = len(generator)
t.addfile(ti, fileobj = GeneratorToFile(generator))
t.close()

您可以创建自己的类似文件的对象并传递给TarFile.addfile文件. 你的类文件对象将在文件对象读取()方法。在

嗯?你不能用subprocess模块来运行管道到tar吗?这样,就不需要临时文件了。当然,如果您不能生成足够小的数据块来容纳RAM,那么这就行不通了,但是如果您有这个问题,那么tar就不是问题所在。在

相关问题 更多 >

    热门问题