Pythonプログラミング:bz2解凍進行状況をtqdmで視覚化

このbz2 decompress code(解凍コード)の難点は、解凍までに冗談と思えるくらい非常に時間がかかるということで、つまり、ある意味で全く使い物にならないということだ。

bz2ファイルの解凍後のサイズは、gzipファイルのようにアーカイブの最後の方の4バイトに書かれてはいないので、以下のように最初から最後までseekすることで解凍後のtotal_sizeサイズを得ることができる。従って、total_sizeを割り出すまでにかなりの時間を要する。

1
2
3
4
f= bz2.BZ2File(fname, 'rb')
f.seek(0, os.SEEK_END)
total_size = f.tell()
f.close()

progress barは前回同様、以下のようにしてtqdmを使えば簡単に作れる

pbar = tqdm(total=total_size, unit='B', unit_scale=True, unit_divisor=1024)

後はbz2 moduleでファイルを読み出して別ファイルに書き込めばbz2を解凍できる。
最終的なコードは、不格好ながら、以下のような簡単なものに仕上がる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from tqdm import tqdm
import bz2
import os.path
import os
fname = "enwiki-latest-pages-articles1.xml-p10p30302.bz2"
f= bz2.BZ2File(fname, 'rb')
f.seek(0, os.SEEK_END)
total_size = f.tell()
f.close()
store_path = os.path.splitext(fname)[0]
pbar = tqdm(total=total_size, unit='B', unit_scale=True, unit_divisor=1024)
fr = bz2.open(fname, 'rb')
with open(store_path, 'wb') as fw:
        for d in fr:
            w = fw.write(d)
            pbar.update(w)

解凍後のスクリーンショットはこんな感じだ。
tqdmでbz2の解凍状況を表示
解凍後のサイズが10Gとかだと、解凍までに1時間くらいかかる可能性がある。実際にbz2ファイルを解凍するなら以下のようにして解凍するのがいいだろう。

1
2
3
4
5
import bz2,shutil

with bz2.BZ2File("enwiki-latest-pages-articles1.xml-p10p30302.bz2") as fr:
    with open("wikidump","wb") as fw:
        shutil.copyfileobj(fr,fw)  # read by 1MB chunks

これだと1分弱で解凍作業が終了するので、tqdmを使うより10倍近くも高速だ。

参考サイトhttps://stackoverflow.com/

スポンサーリンク