多機能なファイルチャネル
ファイルのメモリへのマップ
- map
public MappedByteBuffer map(FileChannel.MapMode mode, long position, long size) throws IOException
ファイルをメモリに直接マップさせます。マップしたファイルへの読み書きは、戻り値のバッファを使用します。バッファへのアクセスはファイルへのアクセスに比べて高速に行えますが、マップしたバッファへの読み書きはオーバヘッドが生じます。
メソッドの第1引数はマップのモードです。モードは3種類で、FileChannel.MapModeクラスで定義されています。
- FileChannel.MapMode.READ_ONLY
- FileChannel.MapMode.READ_WRITE
- FileChannel.MapMode.PRIVATE
PRIVATEは読み書きできますが、書き込んだ結果はファイルに反映されません(copy-on-write)。
第2引数はファイルをファイルをマップする先頭の位置、第3引数はマップするバイト数を示しています。戻り値はマップされたバッファです。
リスト1はファイルのコピーを行う例です(例外処理は省略してあります)。ここではコピー元をマップしています。
FileChannel srcChannel = new RandomAccessFile(srcFile, "r").getChannel(); FileChannel destChannel = new RandomAccessFile(destFile, "rw").getChannel(); // コピー元ファイルをメモリにマップ ByteBuffer buffer = srcChannel.map(FileChannel.MapMode.READ_ONLY, 0, srcChannel.size()); destChannel.write(buffer); srcChannel.close(); destChannel.close();
チャネルの連結
- transferTo
public long transferTo(long position, long count, WritableByteChannel target) throws IOException
- transferFrom
public long transferFrom(ReadableByteChannel src, long position, long count) throws IOException
チャネルの連結を行うにはtransferToメソッド、transferFromメソッドを使用します。
FileChannelオブジェクトの出力を、他のWritableByteChannelオブジェクトの入力にするのがtransferToメソッドです。一方のtransferFromメソッドは他のReadableByteChannelオブジェクトの出力をFileChannelオブジェクトの入力に連結します。
引数のpositionはファイルの転送を開始する位置、sizeは転送するバイト数になります。
リスト2は、transferToメソッドを使用したファイルのコピーです。
FileChannel srcChannel = new FileInputStream(srcFilename).getChannel(); FileChannel destChannel = new FileOutputStream(destFilename).getChannel(); srcChannel.transferTo(0, (int)srcChannel.size(), destChannel); // チャネルの連結 srcChannel.close(); destChannel.close();
ファイルのロック
- lock
public FileLock lock() throws IOException
public FileLock lock(long position, long size, boolean shared) throws IOException
ファイルを使用している時、他のアプリケーションがそのファイルを使用できなくしたり、リードオンリーでしかオープンできなくするのがロックです。前者を排他ロック、後者を共有ロックといいます。
引数のないlockメソッドはファイル全体を排他ロックします。
引数を使用する場合は第1引数がロックの開始位置、第2引数がロックするバイト数、第3引数がロックの種類の指定です。trueが共有ロック、falseが排他ロックです。
排他ロックではチャネルが書き込み可能、また共有ロックでは読み込み可能でなければなりません。
戻り値はFileLockオブジェクトです。ロックを解放するにはFileLock#releaseメソッドを使用します。
リスト3、4にlockの使用法を示します。リスト3が排他ロックの例、リスト4が共有ロックの例です。
FileChannel channel = new FileOutputStream(filename).getChannel(); // ロックをかける。書き込むバイト数が未知なので、sizeは多めにする // FileLock lock = channel.lock(); でも OK FileLock lock = channel.lock(0, Long.MAX_VALUE, false); // 出力処理 channel.close(); lock.release(); // ロックの解放
FileChannel channel = new FileInputStream(filename).getChannel(); FileLock lock = channel.lock(0, channel.size(), true); // ロックをかける // 入力処理 channel.close(); lock.release(); // ロックの解放
(2003.03)