用于读取和写入的 Java 文件锁

2022-09-01 23:14:13

我有一个进程,它将非常频繁地从cron调用,以读取其中具有某些与移动相关的命令的文件。我的进程需要读取和写入此数据文件 - 并保持锁定状态,以防止其他进程在此期间接触它。用户可以执行一个完全独立的过程来(潜在地)写入/追加到同一数据文件。我希望这两个进程发挥良好作用,一次只能访问一个文件。

nio FileLock似乎是我需要的(除了编写我自己的信号量类型文件),但我很难锁定它以供阅读。我可以很好地锁定和写入,但是当读取时尝试创建锁定时,我得到了一个NonWriteableChannelException。甚至可以锁定文件进行读取吗?似乎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());
          ...

在 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)

看看JavaDocs,它说

尝试写入最初未打开进行写入的通道时引发的未选中异常。

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


答案 1
  1. 您是否知道锁定文件不会阻止其他进程接触它,除非他们也使用锁?
  2. 您必须通过可写通道锁定。通过“rw”模式获取锁定,然后打开您的.确保关闭两者!RandomAccessFileFileInputStream

答案 2

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

这创建了一个共享锁,这是阅读的正确方法。

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


推荐