第108回 ファイルチャンネルの入出力
引き続き「ファイルチャンネルの入出力」について見ていきます。
今回はJavaによるファイルロックについて書きます。
Javaによるファイルロックは、FileクラスのcreateNewFileメソッドを使用し、ロック用のファイルの作成することにより実現する方法があります。
しかしJavadoc(J2SE6.0)によると、このメソッドをファイルロックのために使用しないように書かれています。
そこで今回はFileChannelのファイルロック機能を使ってみたいと思います。
このファイルロックは異なる仮想マシンで実行される場合でも有効です。
次のサンプルコードはテキストファイルに書き込むプログラムです。
書き込みはロックを保持した状態でのみ行います。
import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; 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(); public static void main(String[] args) throws Exception { FileChannel fileChannel = null; try { FileOutputStream fileOutputStream = new FileOutputStream("output.txt"); fileChannel = fileOutputStream.getChannel(); FileLock fileLock = fileChannel.tryLock(0, Long.MAX_VALUE, false); if (fileLock != null) { ByteBuffer byteBuffer = ByteBuffer.wrap(BYTE_DATA); for (int i = 0; i < 10; i++) { fileChannel.write(byteBuffer); byteBuffer.rewind(); } } else { System.out.println("書き込みできません。"); } } catch (Exception e) { e.printStackTrace(); } finally { try { fileChannel.close(); } catch (Exception e) {} } } }
FileChannelのtryLockメソッドはファイルの指定された領域のロックを取得しようとします。
ロックを取得した場合、FileLockインスタンスを返しますが、オーバーラップしたロックが別のプログラムによって保持されていたためロックに失敗した場合、nullが返されます。
tryLockメソッドの第三引数は「共有ロック」の場合はtrue、「排他ロック」の場合はfalseを指定します。
このロックはFileLockのreleaseメソッドの実行、チャンネルのクローズ、仮想マシンの終了などによって解放されます。
なお、このファイルロックはオペレーティングシステムに依存します。
例えば、システムによっては「アドバイザリロック」として動作するため、他のプロセスからファイルへのアクセスが可能となってしまう場合があります。