「zipファイルを展開できない」と問い合わせがあって、調べてみたら PK00
つまり PK\30\30 で始まるファイルだった。もろもろ考えた結果、「分割アーカイブには対応していません」という仕様にすることにした。そのときのメモ。
ZIPファイルってそもそもなによ
複数のファイルを圧縮したアーカイブファイルのこと。
zipファイルは通常、PK\03\04や PK\07\08 で始まる圧縮済みファイルブロックと、それらのインデックスである PK\01\02 で始まり PK\05\06 レコードで終わるディレクトリブロックが連結された構造になっている(→Wikipedia)。
ファイル冒頭にある数バイトが特徴的なので、それを検査することで「たぶんzipファイルである」ということがわかる。LINUXのfileコマンドでは、/etc/magic というマジックナンバー定義を使っている。そのZIPファイルの定義は以下のようになっている:
/etc/magic
# PKZIP multi-volume archive
0 string PK\x07\x08PK\x03\x04 Zip multi-volume archive data, at least PKZIP v2.50 to extract
!:mime application/zip
!:ext zip/cbz
# Zip archives (Greg Roelofs, c/o zip-bugs@wkuvx1.wku.edu)
0 string PK\005\006 Zip archive data (empty)
!:mime application/zip
!:ext zip/cbz
0 string PK\003\004
PK00って定義されてないけど……なに?
検索してみたら、PKZIPのAPPNOTE 8.5.4 に記載があった。つまり、PKZIP 2.50以降で作成された、分割アーカイブのようだ。
- StackOverflowだとこんなやりとりがあったり。
- OpenJDKでは BUG 678605 がまだOpenである。
- Oracle Javaでは実装されているけどーという情報もある。 → 動かないらしい。ざんねん。
この問題の検索キーワードは、PK00
またはそのビッグエンディアンの 0x30304b50
です。