2016-05-30 4 views
2

多くのファイルにゼロブロックがあるかどうかを確認する最も早い方法は何ですか?ブロックは、32000バイトのゼロより大きくする必要があります。 次のコードは遅くすることです:ファイル内で32KBを超えるゼロブロックを検出する

empty_blocks = [] 
min_length = 32000 
block = False 
begin = -1 
data = open(file_name,'rb').read() 
for i,byte in enumerate(data): 
     byte = ord(byte) 
     if byte == 0x00 and block == False: 
      block = True 
      begin = i 
     elif byte != 0x00 and block == True: 
      block = False 
      if length >= min_length: 
       empty_blocks.append((begin, i - begin)) 
      begin = -1 
+0

ブロックには、どの整列要件も満たされている必要がありますか?アラインメントの要件が32kでない場合、重複はどうですか? – Flexo

+0

ビットトレント同期プロトコルによって破損したファイル。私はビットトレントプロトコルが転送する最小のピースサイズが32kbであるという情報を得ました。ゼロブロックがn = 1,2,3,4、または32768より大きい値のn * 32kbであるかどうかはわかりません。 –

答えて

3

をので、32768バイトのブロックサイズを想定すると、私は線に沿って何かを思い付いた:

from functools import partial 

BLOCKSIZE = 32 * 1024 

with open('testfile.bin', 'rb') as f: 
    for block_number, data in enumerate(iter(partial(f.read, BLOCKSIZE), b'')): 
     if not any(data): 
      print('Block #{0} is empty!'.format(block_number)) 

sum()を決定するための最速の方法ですシーケンス内のすべてのバイトがゼロの値を持つ場合私はそれがO(n)より速くすることは可能ではないと思います。
VPfBany()を使用することが提案されています。このシーケンスは、シーケンス全体を処理する代わりに、最初の非ゼロ要素で終了するため非常に高速です。

出力例:

Block #0 is empty! 
Block #100 is empty! 
Block #200 is empty! 

それは高速で十分な私は願って私のマシン、上およそ〜100メガバイト/秒 2ギガバイト/秒を処​​理します。ファイルmmappingによって

+1

最初のゼロ以外のバイトが見つかったときにテストを終了する必要があります。 'block_is_empty =何もない(データ)' – VPfB

+0

はい!どうやって明白な何かを見ることができませんでしたか? 今は約20倍速いです、ありがとうございます! – leovp

+0

コードを試しましたが、動作しません。 any(...)は、空のブロックに対してTrueを返します。データ変数には、strにchr(0)の値 –

0

スタート:

for match in re.findall(b'\0{32768}, m): 
    print(match.start()) 

が、文字列はさらに速く、次のとおりです:正規表現を使用して

import mmap, os, re 
f = open(filename) 
m = mmap.mmap(f.fileno(), os.fstat(f.fileno()).st_size, prot=mmap.PROT_READ) 

は便利です

z32k = '\0' * 32768 
start = 0 
while True: 
    start = m.find(z32k, start) 
    if start < 0: 
     break 
    print(start) 

のみ32K-整列ブロック:

for match in re.finditer('.{32768}', m, re.DOTALL): 
    if max(match.group()) == '\0': 
     print(match.start()) 
関連する問題