LoginSignup
0
1

More than 3 years have passed since last update.

Javaでbyte配列をgzip圧縮してファイル出力する

Last updated at Posted at 2021-01-06

タイトルの処理を作成した際に試行錯誤したメモ。

とりあえず書いたソース

こんな感じでbyte配列をgzipにしてファイルに出力してました。
先に別用途でファイル出力する処理を書いていたのを改造した際に、あれこれ調べながら付け足し付け足ししてしまい、今思うと謎に冗長な書き方をしてます。

test.java
        byte[] bytes = output.toByteArray();
        // byte[]をgzip化
        String gzipStr = "";
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            GZIPOutputStream gzip = new GZIPOutputStream(out);
            gzip.write(bytes);
            gzip.close();
            gzipStr = out.toString();
            out.close();
        }catch (IOException e) {
            e.printStackTrace();
            return;
        }
        // gzip化したデータをファイル書き出し
        String file = "出力ファイルパス";
        try(PrintWriter writer = new PrintWriter(
            new BufferedWriter(
            new OutputStreamWriter(
            new FileOutputStream
              (file),"UTF-8")))) {
            writer.print(gzipStr);

        } catch (IOException e) {
            e.printStackTrace();
        }

エラー内容

↑のJavaをコンパイルして実行し、出力したファイルを解凍しようとすると下記のエラーが。

01-05 08:35:22.294 6117-6117/? W/System.err: java.io.IOException: unknown format (magic number ef1f)
01-05 08:35:22.294 6117-6117/? W/System.err:     at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:109)
01-05 08:35:22.294 6117-6117/? W/System.err:     at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:88)
 以下略

恥ずかしながら何もわからず、「gzip マジックナンバーとは」とかでググるところから。(マジックナンバー (フォーマット識別子) - wikipedia)

gzipはファイルの先頭が「1f8b」で始まり、これがマジックナンバー(形式を判断するための符号)なのですが、このファイルは「ef1f」から始まっているためファイル形式が判定できないよということみたいです。

バイナリファイルを確認

Stirlinで出力したファイルを確認してみると、確かに最初が「1f8b」ではないですね。(でも「ef1f」でなく「1fef」のような…)
無題.png

ソース修正

出力時にこねくり回しているのが悪いのかな、と調べて下記サイトを発見。
ANDROIDでGZIPファイルの圧縮・展開をする - TECHBOOSTER

えーこんなにシンプルに書いていいの、と驚きながら参考にさせていただきソースを修正したものがこちら:

test.java
        byte[] bytes = output.toByteArray();
        String file = "出力ファイルパス";
        try {
            GZIPOutputStream gzip = new GZIPOutputStream(new FileOutputStream(file));
            gzip.write(bytes);
            gzip.close();
        }catch (IOException e) {
            e.printStackTrace();
            return;
        }

これでファイル出力したら正常に解凍できました。

バイナリファイルも先頭が「1f8b」になりましたので、大丈夫そうです。
無題.png


諸事情によりIDEを使わずテキストエディタで書いたんですが、importだけですっかり気が滅入りました…JavaはIDEを使おう……

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1