3

ファイルを暗号化し、結果を tarfile に入れるタスクを行う小さな暗号化モジュールを Python で作成しました。暗号化する元のファイルは非常に大きくなる可能性がありますが、それは問題ではありません。なぜなら、私のプログラムは一度に小さなデータ ブロックを操作するだけでよく、その場で暗号化して保存できるからです。

最初にすべてのデータを一時ファイルに書き込み、結果を tarfile に挿入するという 2 つのパスでそれを回避する方法を探しています。

基本的に私は次のことを行います (generator_encryptor は、ソースファイルから読み取ったデータのチャンクを生成する単純なジェネレーターです)。:

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()

ファイルとして一時ファイルを使用しなければならないのは少し面倒です.tarファイルにブロックを直接書き込むのは簡単ですが、すべてのチャンクを単一の文字列に収集し、 t.addfile('content', StringIO( bigcipheredstring) は、古い bigcipheredstring に十分なメモリがあることを保証できないため、除外されているようです。

それを行う方法のヒントはありますか?

4

4 に答える 4

4

独自のファイルのようなオブジェクトを作成して、TarFile.addfile に渡すことができます。ファイルのようなオブジェクトは、fileobj.read() メソッドでオンザフライで暗号化されたコンテンツを生成します。

于 2009-09-07T14:41:10.740 に答える
2

基本的に、ファイルのようなオブジェクトを使用して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()
于 2009-09-20T23:53:26.860 に答える
2

は?subprocessモジュールを使用してパイプを tar に通すことはできませんか? そうすれば、一時ファイルは必要ありません。もちろん、RAM に収まるほど小さいチャンクでデータを生成できない場合、これは機能しませんが、その問題がある場合、tar は問題ではありません。

于 2009-09-07T14:41:20.770 に答える
1

tar 形式がどのように機能するかを理解し、tar の書き込みを自分で処理する必要があると思います。多分これは役に立つでしょうか?

http://mail.python.org/pipermail/python-list/2001-August/100796.html

于 2009-09-07T14:39:04.860 に答える