ひしだまの変更履歴

ひしだまHPの更新履歴。
主にTRPGリプレイの元ネタ集、プログラミング技術メモと自作ソフト、好きなゲームや音楽です。

ZipFileでJISAutoDetect

2009-12-20 23:52:35 | PG(Java)

ZipFileでエンコードにJISAutoDetectを指定すると例外が発生する!というお話があったので、調査。

そもそもJISAutoDetectなんて実務で使ったことが無かったので軽く調べてみると…名前の通り、自動的にエンコードを判別してくれるもので、バイト配列からStringに変換する際に使用できるが、当然String(Unicode)からバイト配列に変換する時には使えない(何に変換すればいいか分からないから。明示的にUnsupportedOperationExceptionがスローされている)。
また、文字列(バイト列)が短すぎると正しく判別できないこともあるらしいが…そりゃしょーがねーっぺ。

ZipFileは解凍に使うものだから、日本語ファイル名のエンコーディングを自動判断してStringに変換する、という意味ではJISAutoDetectが指定できてもおかしくない。
で、何が例外になっているかというと、ZipEntryのコンストラクター。エントリー名(ファイル名)の長さチェックを行っている箇所。指定されたエンコーディング(バイト配列)で長さを取得するので、JISAutoDetectだと駄目なわけだ。
で、そもそもなんでZipEntryで長さチェックを行っているかというと…よく覚えてないけど(爆)、java.util.ZipEntryのコンストラクターで文字数チェックを行っているからだろう。こちらはUnicodeの文字数が65535文字を超えていないかどうかチェックしている(英語圏の人はアルファベットしか使わないから、Unicodeで文字数をチェックしても同じという意識だったんだろうけどなぁ…)んだが、実際に圧縮する際には65535バイトまでしか許容できないから、バイト配列でチェックするようにしたんだと思う。
で、解凍時にZipEntryインスタンスを作成する際にはそもそも長さチェックなんか必要ないわけで。

という訳で、ZipFile関連クラスを修正。
ZipEntryで長さチェックするのをやめた。
そしたらZipEntryでエンコーディングを保持する必要も無いので、encodingフィールドを削除し、encodingを指定するコンストラクターも廃止。
長さチェックはZipOutputStreamの中(圧縮時)で行うように修正。
長すぎる場合に例外発生する箇所が変わってしまったが、…まぁそもそもそんなに長い名前を入れることは無いと思うので、良しとしたい。

全然関係ないが、このZip関連クラス、2007年12月に作って、毎年12月に手を入れているなぁ。
来年は何を直すのやら^^;



最新の画像もっと見る

コメントを投稿