使おうとしてたまに気になって、調べて…を繰り返している気がするので、メモ。
Java 7で追加されたNIO.2の中に、Filesというクラスがあります。この中に、newBufferedReader/newBufferedWriterや、newInputStream/newOutputStreamというメソッドがあり、便利になりました感がありますよね。
ところで、InputStream/OutputStreamの方には「Buffered」が付いていないですよね。メソッド名から考えるとバッファリングされていなさそうですが、どうなのでしょうか?
ちなみに、Reader/Writerの方は戻り値の型がBufferedReader/BufferedWriterですが、InputStream/OutputStreamはバッファリングされていない型になっています。
で、ものは試しとプログラムを用意。ここで、「hello.txt」はすでに存在するファイルとします。
FilesStream.java
import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class FilesStream { public static void main(String... args) throws IOException { try (InputStream is = Files.newInputStream(Paths.get("hello.txt")); OutputStream os = Files.newOutputStream(Paths.get("hello-copy.txt"))) { int b = 0; while ((b = is.read()) != -1) { os.write(b); } } } }
これ、普通に動作しますが途中でちょっとデバッグコードを仕込んでみましょう。
System.out.printf("InputStream class = %s%n", is.getClass().getName()); System.out.printf("OutputStream class = %s%n", os.getClass().getName());
実行すると、こんな結果が出力されます。
InputStream class = sun.nio.ch.ChannelInputStream OutputStream class = java.nio.channels.Channels$1
OutputStreamの方が、わかりやすそうですね。OutpuStreamは、java.nio.channels.Channelsで作成されている内部クラスのようです。ここで、Channels#newOutputStreamの説明は
結果として得られるストリームのwriteメソッドは、基本となるチャネルが非ブロック・モードである場合に呼び出されると、IllegalBlockingModeExceptionをスローします。ストリームはバッファに書き込まれません。ストリームは複数の並行スレッドからのアクセスに対して安全です。ストリームをクローズするとチャネルもクローズします。
なので、バッファリングされていないで正解のようです。
sun.nio.ch.ChannelInputStreamの方も、同様な感じっぽいですね。
いくつか調べてもみましたが、一応正しそうです。
http://docs.oracle.com/cd/E26537_01/tutorial/essential/io/file.html
http://tamanmohamed.blogspot.jp/2012/05/jdk7-using-buffered-io-for-files-in.html
http://www.c-jump.com/bcc/c257c/Week11/W11_0240_example_bufferedoutp.htm
あとは、バッファリングを入れるかどうかは使い方次第ということで。