第105回 ファイルチャンネルの入出力
引き続き「ファイルチャンネルの入出力」について見ていきます。
前回はFileInputStreamのgetChannelメソッドによりFileChannelを取得しましたが、これは読み込み専用のFileChannelです。
書き込み専用のFileChannelはFileOutputStreamのgetChannelメソッドで取得できます。
FileChannelはバイトを書き込むためのWritableByteChannel インターフェース、GatheringByteChannelインターフェースを実装しており、これらのwriteメソッドを実行すると、現在位置(position)からバイトを書き込みます。
ただし、追加モードでは、現在位置をファイルの末尾に設定してからバイトを書き込みます。
また、現在位置は書き込まれた分だけ移動します。
次のプログラムの実行によりチャンネル取得時とwriteメソッド実行直後のpositionの値を確認します。
追加モードで同じ文字列を10行書き込みます。
import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class Main { private static final String LINE_SEPARATOR = System.getProperty("line.separator"); private static final String DATA = "株式会社イーブ" + LINE_SEPARATOR; private static final byte[] BYTE_DATA = DATA.getBytes(); private static final String MESSAGE_FORMAT = "position:%1$d size:%2$d" + LINE_SEPARATOR; public static void main(String[] strings) { FileChannel fileChannel = null; try { FileOutputStream fileOutputStream = new FileOutputStream("output.txt", true); fileChannel = fileOutputStream.getChannel(); messageOut(fileChannel); ByteBuffer byteBuffer = ByteBuffer.wrap(BYTE_DATA); for (int i = 0; i < 10; i++) { fileChannel.write(byteBuffer); messageOut(fileChannel); byteBuffer.rewind(); } } catch (Exception e) { e.printStackTrace(); } finally { try { fileChannel.close(); } catch (Exception e) {} } } private static void messageOut(FileChannel fileChannel) throws Exception { System.out.printf(MESSAGE_FORMAT, fileChannel.position() , fileChannel.size()); } }
実行すると次のように表示されます。
position:0 size:672
position:688 size:688
position:704 size:704
position:720 size:720
position:736 size:736
position:752 size:752
position:768 size:768
position:784 size:784
position:800 size:800
position:816 size:816
position:832 size:832
ちなみに、FileChannelクラスにはチャネルの現在位置に影響を及ぼすことなく、ファイル内の絶対位置から書き込むwriteメソッドも存在します。(sizeは影響を受けます。)