2016-11-10 9 views
1

いくつかのファイルが非常に大きいいくつかのファイルにxOr操作を適用しようとしています。
基本的に私はファイルを取得しており、バイトごとにxor-ingしています(少なくともこれは私がやっていると思います)。大きなファイル(約70MB)にヒットすると、メモリ不足のエラーが発生し、スクリプトがクラッシュします。
私のコンピュータには16GBのRAMがあり、その50%以上が使用可能なので、これは私のハードウェアには関係しません。大きなファイルをPythonで解凍する

def xor3(source_file, target_file): 
    b = bytearray(open(source_file, 'rb').read()) 
    for i in range(len(b)): 
     b[i] ^= 0x71 
    open(target_file, 'wb').write(b) 

私はチャンクでファイルを読み込もうとしましたが、出力が所望のものではないとして、私はこのためにあまりにもunexperimentedだそうです。最初の機能はもちろん、私が欲しいものを返す:)

def xor(data): 
    b = bytearray(data) 
    for i in range(len(b)): 
     b[i] ^= 0x41 
    return data 


def xor4(source_file, target_file): 
    with open(source_file,'rb') as ifile: 
     with open(target_file, 'w+b') as ofile: 
      data = ifile.read(1024*1024) 
      while data: 
       ofile.write(xor(data)) 
       data = ifile.read(1024*1024) 


をこの種の操作のためのappropiateソリューションとは何ですか?私は間違って何をしているのですか?大容量のファイルを超える遅延し

+0

あなたが0x71' 'とのXOR機能の一つで、ファイル –

+0

の内容は何その他は '0x41'となります。これはあなたが期待したものですか?明らかにこれは結果を変えます... – Bakuriu

+0

@Bakuriu私はちょうど異なるキーを使って別のファイルで試していました。 –

答えて

2

たびに、チャンクでファイルを取得し、それを追加するために使用seek機能出力ファイルに

CHUNK_SIZE = 1000 #for example 

with open(source_file, 'rb') as source: 
    with open(target_file, 'a') as target: 
     bytes = bytearray(source.read(CHUNK_SIZE)) 
     source.seek(CHUNK_SIZE) 

     for i in range(len(bytes)): 
      bytes[i] ^= 0x71 

     target.write(bytes) 
+0

私はこれを試して、それはファイルの最初のチャンクを処理するように見えます。私はそれを修正することができれば私はここで更新されます。 –

0

反復。

from operator import xor 
from functools import partial 
def chunked(file, chunk_size): 
    return iter(lambda: file.read(chunk_size), b'') 
myoperation = partial(xor, 0x71) 

with open(source_file, 'rb') as source, open(target_file, 'ab') as target: 
    processed = (map(myoperation, bytearray(data)) for data in chunked(source, 65536)) 
    for data in processed: 
     target.write(bytearray(data)) 
+1

注意:センチネル値には '' ''の代わりに' b'''を使うべきです。また、ターゲットファイルもバイナリモードでオープンしていなければなりません。 'a'ではなく' ab'です。これらの2つの簡単な変更により、コードはpython2とpython3の両方で動作します。 – Bakuriu

0

私が間違っていない限り、あなたの第二の例では、あなたはbytearrayを呼び出し、bに割り当てることによってdataのコピーを作成します。その後、bを変更しますが、dataを返します。 bの変更はdata自体には影響しません。

+0

それは本当です!その場をありがとう。 –

0
これはおそらく唯一それがbytestreamsに使用する非常に良くだことを改めて示しパイソン2、で動作

def xor(infile, outfile, val=0x71, chunk=1024): 
    with open(infile, 'r') as inf: 
     with open(outfile, 'w') as outf: 
      c = inf.read(chunk) 
      while c != '': 
       s = "".join([chr(ord(cc) ^val) for cc in c]) 
       outf.write(s) 
       c = inf.read(chunk) 
関連する問題