この機能は、SeekableByteChannelインタフェースによって実現されます。 SeekableByteChannelインタフェースによりチャネルI/Oが拡張され、現在の位置を認識できるようになります。 メソッドを使用して位置の設定または問合せができ、その位置からデータを読み取ったり書き込んだりすることができます。 このAPIはいくつかの使用しやすいメソッドで構成されています。
position – チャネルの現在の位置を返します。
position(long) – チャネルの位置を設定します。
read(ByteBuffer) – チャネルからバッファにバイトを読み取ります。
write(ByteBuffer) – バッファからチャネルにバイトを書き込みます。
truncate(long) – チャネルに接続されたファイル(またはその他のエンティティ)を切り詰めます。
チャネルI/Oを使用したファイルの読取りと書込みでは、Path.newByteChannelメソッドがSeekableByteChannelのインスタンスを返すことが説明されています。 デフォルトのファイル・システムでは、このチャネルをそのまま使用することも、FileChannelにキャストして、より高度な機能を利用することもできます。たとえば、ファイルの一部の領域をメモリに直接マップしてアクセスを高速化する、ファイルの一部の領域をロックする、チャネルの現在の位置に影響を及ぼさずに絶対位置からバイトの読取りまたは書込みを行うといった機能が利用できます。
次のコードでは、newByteChannelメソッドの1つを使用して、ファイルを読取り用と書込み用にオープンします。 返されたSeekableByteChannelを、FileChannelにキャストしています。 次に、ファイルの先頭から12バイトを読み取り、その位置に"I was here!"という文字列を書き込みます。 現在の位置をファイルの末尾に移動し、先頭で読み取った12バイトを追加します。 最後に、"I was here!"という文字列を追加し、そのファイルへのチャネルをクローズします。
String s = "I was here!\n";
byte data[] = s.getBytes();
ByteBuffer out = ByteBuffer.wrap(data);
ByteBuffer copy = ByteBuffer.allocate(12);
try (FileChannel fc = (FileChannel.open(file, READ, WRITE))) {
//ファイルの先頭の12バイトを読み取ります。
int nread;
do {
nread = fc.read(copy);
} while (nread != -1 && copy.hasRemaining());
//ファイルの先頭から"I was here!"を書き込みます。
fc.position(0);
while (out.hasRemaining())
fc.write(out);
out.rewind();
//ファイルの末尾に移動し、先頭で読み取った12バイトをファイルの
//末尾にコピーします。次に、"I was here!"を再度書き込みます。
long length = fc.size();
fc.position(length-1);
copy.flip();
while (copy.hasRemaining())
fc.write(copy);
while (out.hasRemaining())
fc.write(out);
} catch (IOException x) {
System.out.println("I/O Exception: " + x);
}