GZIPOutputStream と ByteArrayOutputStream と try with resources
Java の try with resources
は途中で return
してもリソースの close
をしてくれるけど、なんか間違えた。
GZIPOutputStream
と ByteArrayOutputStream
を使って以下のような、データを圧縮してバイト列にして返す処理を書いていました。( InputStream
の部分は実際は外部のファイルのストリームとかになると思います)
String input = "hogehogehoge"; InputStream in = new ByteArrayInputStream(input.getBytes()); try ( BufferedReader reader = new BufferedReader(new InputStreamReader(in)); ByteArrayOutputStream out = new ByteArrayOutputStream(); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new GZIPOutputStream(out))) ) { String line; while ((line = reader.readLine()) != null) { writer.write(line); writer.newLine(); } return out.toByteArray(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); }
すると次の例外が発生。
java.io.EOFException: Unexpected end of ZLIB input stream
これは GZIPOutputStream を閉じていないときに出る例外で、「 try with resources
だから閉じられるのでは?」と思いましたが、 toByteArray
しているタイミングはまだ処理が try
を抜けていないので閉じられていなかったようです。
以下のように変更して解決しました。バイト列を取得するのは try
を抜けてから行うようにしました。
String input = "hogehogehoge"; InputStream in = new ByteArrayInputStream(input.getBytes()); ByteArrayOutputStream out = new ByteArrayOutputStream(); try ( BufferedReader reader = new BufferedReader(new InputStreamReader(in)); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new GZIPOutputStream(out))) ) { String line; while ((line = reader.readLine()) != null) { writer.write(line); writer.newLine(); } } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); } return out.toByteArray();
感想
すぐ終わると思って書いたコードが動かなくて夜が明けてしまった。
最近景気が悪いので、仕事がなくなったら各地のお祭りを巡る旅とかしたい。