検索
連載

意外と知らないファイル圧縮技術の常識プログラマーの常識をJavaで身につける(8)(3/4 ページ)

本連載は、Java言語やその文法は一通り理解しているが、「プログラマー」としては初心者、という方を対象とします。Javaコアパッケージを掘り下げることにより「プログラマーの常識」を身に付けられるように話を進めていきます。今回はアーカイブと圧縮の違いなどの基礎知識とともに、Java APIでJava定番のファイル圧縮形式jarやgzip、zip形式を扱う方法も紹介。

PC用表示 関連情報
Share
Tweet
LINE
Hatena

java.util.zipパッケージでzipファイルを操作

zipファイル形式の概要

 zip形式には、ファイル圧縮機能とアーカイブ機能があります。アーカイブ機能がある分、gzip形式よりも複雑です。このため、zip形式を扱うJava APIも、より複雑な構造になっています。

 zipファイルを標準APIで利用できるのはとても便利ですが、残念なことに、ここで注意しなければならない点をお知らせしなくてはなりません。

zipファイル名の文字コードによる悲劇

 java.util.zipパッケージのzipファイル入出力は、zipファイルをアーカイブする際にファイル名としてUTF-8文字エンコーディングを利用しています。これはさまざまな国と地域で利用されるJava言語にとって自然な判断なのでしょう。ところが、世間一般に出回っているzipファイルを扱うためのユーティリティプログラム(「アーカイバ」などと呼ばれる)はUTF-8文字エンコーディングによるファイル名に対応していないものがほとんどなのです。

 Windows用のものはShift_JIS文字エンコーディング(正確には、Windows-31J文字エンコーディング)でファイル名が格納されていると仮定したものが多いのです(Windows XP標準で提供されているzip形式関連機能も同様です)。

 このサンプルプログラムでISO/IEC 646(通称、ASCIIコード)の文字以外の文字を利用したファイル名を含んだzipファイルの入出力を行うと、トラブルに遭遇する場合がありますので、ご注意ください(ISO/IEC 646(通称、ASCIIコード)については連載第6回「‘愛’で学ぶ文字コードと文字化けの常識」の「文字化けには問題がこんなにたくさんある!」を参照してください)。

zipファイルを作成するサンプル

 zipファイルを作成するためには、java.util.zip.ZipOutputStreamクラスを利用します。java.util.zip.GZIPOutputStreamと異なり、java.util.zip.ZipEntryというアーカイブに含まれるファイルやディレクトリを表すクラスを利用しながら、ファイル圧縮およびアーカイブを行います。java.util.zip.ZipOutputStreamにより圧縮されて連結先の出力ストリーム(この例では、java.io.BufferedOutputStream)に書き込まれていきます。

*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***

実行結果(コンソール出力)

zipファイル作成: 開始: C:\Documents and Settings\iga\workspace\aaa\zipsample.zip

zipファイル作成: 終了


 このプログラムが作成したzipファイルを[エクスプローラ]で表示すると、下記のようになります。

 なお、Java APIを利用してディレクトリを作成すると、下記の「ABC」のように、ディレクトリ実体と余分なエントリの2つが作成されます。これは現状のJava APIの仕様上、仕方がないようです(Javaツールのjarコマンドにおいても同様の現象が発生します)。

図13 作成されたzipファイル
図13 作成されたzipファイル

zipファイルを読み込むサンプル

 次に、作成したzipファイルを展開(解凍)しながら読み込むサンプルプログラムを見ていきましょう。

 なお、このサンプルも、直前で示したCreateZipSampleが作成したzipファイルを読み込むという仮定の下に作られています。具体的には、ファイル名はUTF-8文字エンコーディング、読み込まれるデータは少量のテキストファイルであり、かつ同じデフォルト文字エンコーディング環境で動作しているものと仮定しています。

*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***

 ここでは、java.util.zip.ZipInputStreamクラスを使用しています。連結先の入力ストリーム(ここでは、java.io.BufferedInputStream)からデータを読み込んで、java.util.zip.ZipEntryを取り出してアーカイブ前のディレクトリおよびファイルの情報を取り出し、zip形式で展開(解凍)しながら読み込んでいます。

実行結果(コンソール出力)

zipファイル読込: 開始: C:\Documents and Settings\iga\workspace\aaa\zipsample.zip

ディレクトリ名: [ABC/]

ファイル名: [ABC/ABC.txt]

内容: [あいうえお]

ファイル名: [ABC/DEF.txt]

内容: [かきくけこ]

ファイル名: [GHI.txt]

内容: [さしすせそ]

zipファイル読込: 終了


 いよいよ次ページでは、Javaに欠かせないjar形式を見ていきます。

java.util.jarパッケージでjarファイルを操作

Copyright © ITmedia, Inc. All Rights Reserved.

ページトップに戻る