昨日の 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がなにかしているのかも)、やっぱりバグですな。