.zipファイルが解凍できないケースを発見したのでメモ。
Windowsのエクスプローラで2GiB以上のファイルを圧縮して作成した.zipの場合、
C#、python、PowerShellのプログラムで.zipを解凍できません。
その他の言語は未確認です。
Windowsエクスプローラの圧縮方式
Windowsエクスプローラの圧縮方式は、圧縮対象のサイズによって変化します。
- 2GiB未満のファイルを圧縮するときは、Deflate方式
- 2GiB以上のファイルを圧縮するときは、Deflate64方式
になるようです。
それぞれの詳細な圧縮アルゴリズムは不明ですが、Deflate64のほうが圧縮率が高い模様。
実際に比較してみました。
「1GB」:サイズ1GiBのファイル
「2GB」:サイズ2GiBのファイル
「1GB.zip」:「1GB」をWindowsエクスプローラで圧縮したファイル
「2GB.zip」:「2GB」をWindowsエクスプローラで圧縮したファイル
「1GB.zip」と「2GB.zip」のサイズを見てみると、
「1GB.zip」:1020KB
「2GB.zip」:73KB
となっています。もともと「2GB」のほうが倍のファイルサイズだったにも関わらず、
Windowsエクスプローラで圧縮すると「2GB.zip」の方が1/10以上小さくなっています。
※ちなみに「1GB」「2GB」共にfsutilというコマンドで作成したため、ファイルの内容によって圧縮率が異なるというのは考えにくいです。
色々調べた結果、2GiB未満のファイルはDeflate方式、2GiB以上のファイルはDeflate64方式で圧縮されていることがわかってきました。
Deflate64方式の圧縮ファイルは解凍できない
圧縮方式がDeflateだろうがDeflate64だろうがプログラムで解凍できれば良いのですが、うまくいきません。
試しにpythonで「2GB.zip」を解凍するプログラムを実施してみます。
■プログラム
with zipfile.ZipFile('2GB.zip') as z: z.extractall('extract/')
■結果
--------------------------------------------------------------------------- NotImplementedError Traceback (most recent call last) <ipython-input-7-51738e0901c8> in <module>() 1 with zipfile.ZipFile('2GB.zip') as z: ----> 2 z.extractall('extract/') 省略 NotImplementedError: compression type 9 (deflate64)
のようなエラーになります。
pythonでは、deflate64方式で圧縮されたファイルの解凍に対応していないようです。
C#、PowerShellで実装しても同様の結果になります。
ちなみに、Deflate方式で圧縮されたであろう「1GB.zip」は上述のプログラムで解凍できました。
また、「2GB」をpythonで圧縮すると2040KBの圧縮ファイルになります。
ちょうど「1GB.zip」の2倍のサイズです。
このpythonで圧縮したファイルは、当然pythonで解凍することができました。
まとめ
現状、pythonやC#、PowerShellでDeflate64方式で圧縮された圧縮ファイルを解凍する術はないようです。
7-zipというフリーの圧縮/解凍ツールはコマンドベースでファイルの解凍が実施でき、なおかつDeflate64方式に対応しているようです(※未確認)。
どうしてもプログラムでDeflate64方式の圧縮ファイルをプログラムで解凍したい場合は7-zipの導入を検討すべきかもしれません。
以上!!
コメント