在Java中锁定文件的存在

时间:2014-11-10 18:45:53

标签: java file locking

简短版本:为什么File.createNewFile()不能用于文件锁定?或者更具体地说:如果用于锁定应用程序数据目录会有问题吗?


详细信息:

我想使用锁定文件保护我的应用程序数据目录:如果文件lock存在,则目录被锁定,应用程序退出并显示错误消息。如果它不存在,将创建它并继续应用程序。退出时,文件将被删除。

不会经常创建锁(即性能不是问题),如果出现某些错误,手动删除锁定文件没有问题(即无法删除文件不成问题)。

代码看起来像这样:

File lockFile = new File("lock");
boolean lockCreated = lockFile.createNewFile();
if (lockCreated)
{
    // do stuff
    lockFile.delete();
}
else
{
    System.err.println("Lockfile exists => please retry later");
    // alternative: Wait and retry e.g. 5 times
}

现在我对Javadoc of createNewFile()

感到有些困惑
  

当且仅当具有此名称的文件尚不存在时,才会以原子方式创建一个由此抽象路径名命名的新空文件。 检查文件是否存在以及文件的创建(如果不存在)是针对可能影响文件的所有其他文件系统活动的单个操作

     

注意:此方法应该用于文件锁定,因为无法使生成的协议可靠地工作。 FileLock工具应该是反而用了。

考虑到存在检查和文件创建是原子的,注释中提到的潜在问题是什么?

从2007年12月开始,{p> This forum post表明存在重要的平台差异"根据{{​​3}}的Javadoc(尽管至少从Java SE 1.4.2开始我找不到这样的声明)。但即使存在这样的差异:它们真的会导致锁定失败(即两个进程认为数据目录同时可用)吗?


注意:需要以下任何内容:

  • 锁定文件,以便其他进程无法访问和/或修改它(我发现的大多数信息似乎都在讨论此问题)。
  • 确保没有其他进程可以移除锁定。
  • 同步同一个JVM的多个线程(虽然我认为我的解决方案也应该能够处理它)。

2 个答案:

答案 0 :(得分:1)

简短的回答:Java中基于可靠文件的锁定是不切实际的。

答案很长:在任何操作系统中,基于文件的锁定问题总是归结为文件来自哪种存储系统。几乎所有网络访问的文件系统(NFS,SAMBA等)都有非常不可靠(或至少是不可预测的)同步文件创建或删除,这使得一般的Java-ish方法不可取。在某些操作系统中,使用本地文件系统,有时可以获得所需的内容。但是你需要了解底层文件系统及其特性,并小心谨慎。

答案 1 :(得分:1)

Files.createFile(…)的Javadoc,自Java 7以来可用的java.nio.file的一部分,重复了原子性的承诺,但没有提到任何关于基于文件的锁定。

我的推理:

  • 较新的方法(来自java.nio.file.Files)受到与旧版本(来自java.io.File)相同(或类似)问题的影响,而Javadoc只是缺少此信息...
  • ...或者更新的方法实际上表现得更加可预测和正确。

鉴于错误处理和java.nio.file中的规范与File类(自JDK 1.2以来存在)相比通常得到了改进,我认为第二种选择是正确的。

我的结论:使用Files.createFile(…)对于这个用例很好。