AndroidでGZIPファイルの圧縮・展開をする


「AndroidでZIPファイルの圧縮・展開をする」ではAndroidアプリでZIPファイルを圧縮、および展開する方法について解説しました。
今回はAndroidアプリでGZIPファイルを扱う方法について解説します。

GZIPは多くのUNIXで標準搭載されている圧縮形式です。
ファイルアーカイバの機能を持たないため、複数のファイルやディレクトリを1つにまとめることはできません。
しかしながら、UNIX上では標準入出力を介してデータの圧縮・展開を行えることため、様々な用途で利用されています。

また、HTTP1.1以降でサポートされているデータ圧縮機能のフォーマットとしてgzipを
利用することが可能であるため、HTTP通信を行うAndroidアプリでgzipを利用することで
通信料を減らすことが可能
になります。
(HTTP通信でgzipを利用する方法については別途解説します)

AndroidでGZIP形式のファイルを扱うために必要なのは下記2つのクラスです。

  • GZIPInputStreamクラス
  • GZIPOutputStreamクラス

GZIP形式でもZIPファイルを扱う場合と同様に、GZIP形式のファイルを書き出す場合にはGZIPOutputStreamクラスを、GZIP形式のファイルを読み込む場合にはGZIPInputStreamクラスを使います。

続きからサンプルコードを紹介します。

GZIP形式でファイルを圧縮する

まずはGZIP形式でファイルを圧縮する手順を紹介しましょう。
上記で述べたように、GZIP形式は複数のファイルをまとめて圧縮することはできません。
単一のデータストリームに対して圧縮処理を行います。

下記はSDカードなどのストレージに保存されているJPEGファイルをGZIP圧縮するサンプルコードです。

■GzipArchiverActivity.java

public void compress(String inputFile, String outputFile) {
    // 入力ストリーム
	InputStream is = null;

    // GZIP形式の出力ストリーム
	GZIPOutputStream gzos = null;

    // 出力バッファ
	byte[] buf = new byte[1024];

	try {
		// 入力ストリームを作成する
		is = new FileInputStream(inputFile);

        // GZIP形式の出力ストリームを作成する
		gzos = new GZIPOutputStream(new FileOutputStream(outputFile));

        // 入力ストリームから出力ストリームへ書き出す
		int len = 0;
		while ((len = is.read(buf)) != -1) {
			gzos.write(buf, 0, len);
		}

        // 入力ストリームを閉じる
		is.close();

		// 出力ストリームを閉じる
		gzos.close();

		tv.setText("compress successful!");
	} catch (FileNotFoundException e1) {
		e1.printStackTrace();
		tv.setText("FileNotFoundException");
	} catch (IOException e1) {
		e1.printStackTrace();
		tv.setText("IOException");
	}
}

まず、1行目のメソッド定義ですが、引数には入力元となるファイルのパスと出力先となるGZIPファイルのパスを指定します。
13行目でファイルからの入力ストリームを作成し、16行目でGZIP形式の出力ストリームを作成します。
そして、20〜22行目で入力ストリームから読み出したデータをそのままGZIP形式の出力ストリームへ書き出しています。

GZIP形式でファイルを展開する

次にGZIP形式で圧縮されたファイルを展開してみましょう。

■GzipArchiverActivity.java

public void extract(String inputFile) {
    // GZIP形式の入力ストリーム
	GZIPInputStream gzis = null;

	// 出力ストリーム
	BufferedOutputStream os = null;

    // 入力バッファ
	byte[] buf = new byte[1024];

	try {
		// GZIP形式の入力ストリームを作成する
		gzis = new GZIPInputStream(new FileInputStream(inputFile));

		// 出力ストリームを作成する
		os = new BufferedOutputStream(new FileOutputStream(EXTRACT_FILENAME));

        // 入力ストリームから出力ストリームへ書き出す
		int len = 0;
		while ((len = gzis.read(buf)) != -1) {
			os.write(buf, 0, len);
		}

        // 入力ストリームを閉じる
		gzis.close();

        // 出力ストリームを閉じる
		os.close();

		tv.setText("extract successful!");
	} catch (FileNotFoundException e) {
		e.printStackTrace();
		tv.setText("FileNotFoundException");
	} catch (IOException e) {
		e.printStackTrace();
		tv.setText("IOException");
	}
}

1行目、extractメソッドの引数はGZIPで圧縮されたファイルのパスです。
13行目でGZIP形式の入力ストリームを作成するときに、引数で与えられたGZIPファイルのパスを指定します。
そして、16行目で出力ストリームを作成し、20行目〜22行目にかけてGZIP圧縮されたデータを書き出しています。

以上、お疲れさまでした。