昨日の PrintWriter の件
昨日のPrintWriterの件に激しく誤解した「仕様です」との指摘が来たので説明ついでに検証しておく。
別に、生成したストリームを全部、個別に close しないといけないといったわけじゃなくて、
writer = new OutputStreamWriter(new FileOutputStream(file), encoding);
だと、invalid なエンコーディングを指定された場合に、OutputStreamWriter のコンストラクタが UnsupportedEncodingException を投げるわけで、そのとき writer は null になると。で、その場合、すでに生成された FileOutputStream のインスタンスがどこからも参照されていないので、close できないという話。
で、一応検証。プラットフォームは FreeBSD。
% cat PrintWriterTest.java import java.io.File; import java.io.PrintWriter; import java.io.IOException; import java.io.UnsupportedEncodingException; public class PrintWriterTest { public static void main(String[] args) throws IOException { File dir = new File("tmp"); String encoding = "dummy"; if (!dir.exists()) { dir.mkdirs(); } for (int i = 0; i < 1000; i++) { String filename = String.format("%05d", i); File file = new File(dir, filename); PrintWriter out = null; try { out = new PrintWriter(file, encoding); } catch (UnsupportedEncodingException ex) { } finally { if (out != null) { out.close(); } } } } } % javac PrintWriterTest.java % ulimit -n 30 % java PrintWriterTest Exception in thread "main" java.io.FileNotFoundException: tmp/00176 (Too many open files) at java.io.FileOutputStream.open(Native Method) at java.io.FileOutputStream.<init>(FileOutputStream.java:179) at java.io.FileOutputStream.<init>(FileOutputStream.java:131) at java.io.PrintWriter.<init>(PrintWriter.java:252) at PrintWriterTest.main(PrintWriterTest.java:21)
同時オープン数を30に制限したはずなのに 177 回目で「Too may open files」になるのがかなり謎ではあるが(finalizerがなにかしているのかも)、やっぱりバグですな。