我正在创建一个用于打开和编辑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),该应用程序的其他实例现在可以访问正在编辑的文件。
我发现这种行为很奇怪。 谁能解释为什么会这样呢?
我希望上述内容有意义。 提前谢谢!
答案 0 :(得分:7)
来自FileLock JavaDocs:
锁是否实际阻止其他程序访问锁定区域的内容是系统相关的,因此未指定。
您的平台仅提供咨询锁定。持有咨询锁不会阻止其他进程访问该文件。
因此,锁定文件实际上只是挂出“请勿打扰”的标志,但是让门保持解锁状态。如果每个人都阅读并尊重这个标志,你就会很好,但这并不能阻止任何人走进去。
JavaDocs还明确指出:
代表整个Java虚拟机保存文件锁。它们不适合控制同一虚拟机中多个线程对文件的访问。
如果您的代码在应用程序服务器中运行,则文件锁定将无法满足您的需求。