java.io.BufferedInputStream の挙動
C++ だとか MIBファイルを書くための英文を書くとか、違う仕事が多かったが、今日は久しぶりに仕事で Java のコードを書いた。
Jar ファイルに埋め込んだテキストファイルの内容を読むコードを書いていた。
public void readResource() throws IOException { InputStream in = getClass().getResourceAsStream(RESOURCE_NAME); BufferedReader br = new BufferedReader(new InputStreamReader(in)); br.mark(256); String line = br.readLine(); : br.reset(); : }
すると、mark() して reset() すると、IOException が発生する!
java.io.IOException: Resetting to invalid mark at java.io.BufferedInputStream.reset(BufferedInputStream.java:368) :
BufferedReader#markSupported() をチェックしてみるが、true が返されている。
なぜ reset() できないんだろう???
原因が分からないまま、次のようにコードを変更してみるとうまくいくようになった。
public void readResource() throws IOException { InputStream in = getClass().getResourceAsStream(RESOURCE_NAME); ByteArrayInputStream bis = toByteArrayInputStream(is); BufferedReader br = new BufferedReader(new InputStreamReader(in)); br.mark(256); String line = br.readLine(); : br.reset(); : } private ByteArrayInputStream toByteArrayInputStream(BufferedInputStream bis) throws IOException { StringBuffer sb = new StringBuffer(); BufferedReader br = new BufferedReader(new InputStreamReader(bis)); while(br.ready()){ sb.append(br.readLine()); sb.append("\n"); } byte b[] = sb.toString().getBytes(); return new ByteArrayInputStream(b); }
読み込んでいるファイルのサイズは1KBもない小さなものだ。それに、mark()している場所までのサイズはたったの256バイト。BufferedReader のデフォルトバッファサイズは8KBなので、ファイル全体を読み込むにも十分なのに。
納得がいかない。(けど、動いたからいいか。)