Java文件锁定机制(FileLock等)存在问题

7
我正在创建一个简单的应用程序,用于打开和编辑XML文件。这些文件位于本地文件夹中,可以被多个应用程序实例访问。我想要做的是锁定每个被应用程序实例打开的文件,以防其他实例访问它。
为了实现这一点,我使用以下代码:
function void readFile(){
   File xmlFile = new File("myFile.xml");
   RandomAccessFile raf = new RandomAccessFile(xmlFile, "rw");
   FileLock fl = raf.getChannel().tryLock();

   if(fl==null){
       System.out.println("file already locked by another instance");
   }else{
       setCurrentFile(raf);
       setLock(fl);
       System.out.println("file successfully locked by this instance");
   }  

由于我希望在编辑文件时保持锁定状态,因此我不关闭 raf 也不释放 fl。

此时,任何试图访问被锁定文件的应用程序实例都无法成功。到目前为止还不错。

我观察到以下奇怪的现象:

如果在获取文件锁之后,在同一文件上打开 FileInputStream,即使 FileLock 对象仍然有效(isValid 返回 true),其他应用程序实例现在也可以访问正在编辑的文件。

我觉得这个行为很奇怪。 有人能解释一下为什么会发生这种情况吗?

希望以上内容清晰明了。 提前感谢!


Windows?Linux?MacOS?文件锁定确实是操作系统的功能。 - bmargulies
1
我已在MacOS和WindowsXP上对此进行了测试。我知道不同底层操作系统可能会对锁定进程造成影响。虽然如此,但我不认为这与操作系统有任何关系。谢谢! - KostasT
看起来像是JDK的一个bug。你尝试过提交一个bug请求吗? - Desik
1个回答

8

根据FileLock JavaDocs:

锁是否实际阻止其他程序访问锁定区域的内容取决于系统,因此未指定。

你的平台只提供了咨询锁定。持有咨询锁将不会阻止其他进程访问文件。

因此,锁定文件实际上只是挂出“请勿打扰”的标志,但保持门未锁上。如果每个人都遵守并尊重标志,那么就很好,但这并不能阻止任何人走进来。

JavaDocs还明确说明:

文件锁定代表整个Java虚拟机。它们不适用于通过同一虚拟机内的多个线程控制对文件的访问。

如果你的代码在应用服务器中运行,文件锁定将无法满足你的需求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接