用于读写的Java FileLock

bob*_*wl2 22 java file-locking filelock

我有一个进程,它会被cron相当频繁地调用,以读取其中包含某些与移动相关的命令的文件.我的进程需要读取和写入此数据文件 - 并将其锁定以防止其他进程在此期间触摸它.用户可以执行完全独立的过程(可能)写入/附加到该相同的数据文件.我希望这两个进程运行良好,并且一次只访问一个文件.

nio FileLock似乎是我需要的(没有编写我自己的信号量类型文件),但是我无法将其锁定以供阅读.我可以锁定并写入正常,但在读取时尝试创建锁定时会出现NonWritableChannelException.甚至可以锁定文件进行阅读吗?看起来像RandomAccessFile更接近我的需要,但我不知道如何实现它.

这是失败的代码:

FileInputStream fin = new FileInputStream(f);
FileLock fl = fin.getChannel().tryLock();
if(fl != null) 
{
  System.out.println("Locked File");
  BufferedReader in = new BufferedReader(new InputStreamReader(fin));
  System.out.println(in.readLine());
          ...
Run Code Online (Sandbox Code Playgroud)

FileLock行抛出异常.

java.nio.channels.NonWritableChannelException
 at sun.nio.ch.FileChannelImpl.tryLock(Unknown Source)
 at java.nio.channels.FileChannel.tryLock(Unknown Source)
 at Mover.run(Mover.java:74)
 at java.lang.Thread.run(Unknown Source)
Run Code Online (Sandbox Code Playgroud)

它说,看看JavaDocs

尝试写入最初未打开以进行写入的通道时,抛出未经检查的异常.

但我不一定要写信给它.当我尝试创建FileOutpuStream等用于写入目的时,我很高兴,直到我尝试在同一文件上打开FileInputStream.

use*_*421 17

(a)您是否知道锁定文件不会阻止其他进程接触它,除非它们也使用锁?
(b)你必须通过可写信道锁定.通过RandomAccessFile"rw"模式获取锁定,然后打开您的FileInputStream.一定要关闭它们!

  • a) 是的,我将编写两个进程并计划在两个进程中实现类似的锁定过程 b) 我没有意识到您可以直接在 RandomAccessFile 上获得锁定。要使用 File[Input|Output]Stream,我需要做一个新的 FileInputStream(raf.getFD())。但是,无论哪种方式直接使用 RandomAccessFile 对象的输入流,我仍然可以从文件中读取。谢谢 (2认同)

Hux*_*uxi 13

如果你使用创建锁会更好tryLock(0L, Long.MAX_VALUE, true).

这会创建一个共享锁,这是阅读的正确选择.

tryLock()是一个简写tryLock(0L, Long.MAX_VALUE, false),即它请求一个独占的写锁.

  • 我是这样写的,因为阅读不是互相排斥的.它实际上是可能的多个线程从一个文件,而不干扰而写作总是独占读取.请记住,这是对原始问题的回答,并不是每种情况的绝对真理.不过,在99%的用例中都是如此. (2认同)