タイトルの処理を作成した際に試行錯誤したメモ。
とりあえず書いたソース
こんな感じでbyte配列をgzipにしてファイルに出力してました。
先に別用途でファイル出力する処理を書いていたのを改造した際に、あれこれ調べながら付け足し付け足ししてしまい、今思うと謎に冗長な書き方をしてます。
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」のような…)
##ソース修正
出力時にこねくり回しているのが悪いのかな、と調べて下記サイトを発見。
ANDROIDでGZIPファイルの圧縮・展開をする - TECHBOOSTER
えーこんなにシンプルに書いていいの、と驚きながら参考にさせていただきソースを修正したものがこちら:
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」になりましたので、大丈夫そうです。
諸事情によりIDEを使わずテキストエディタで書いたんですが、importだけですっかり気が滅入りました…JavaはIDEを使おう……