java - Java 中文件存在的锁定

标签 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() 有点困惑:

Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist. The check for the existence of the file and the creation of the file if it does not exist are a single operation that is atomic with respect to all other filesystem activities that might affect the file.

Note: this method should not be used for file-locking, as the resulting protocol cannot be made to work reliably. The FileLock facility should be used instead.

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

This forum post从 2007 年 12 月开始,根据 File.delete() 的 Javadoc 表明存在“显着的平台差异” (尽管至少从 Java SE 1.4.2 起我就找不到这样的说法)。但即使存在这样的差异:它们真的会导致锁定失败(即两个进程同时认为数据目录可用)吗?

<小时/>

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

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

最佳答案

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

<小时/>

我的推理:

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

考虑到 java.nio.file 中的错误处理和规范与 File 类(自 JDK 1.2 起就存在)相比总体上得到了改进,我认为第二种选择是正确的。

<小时/>

我的结论:使用 Files.createFile(…) 适合此用例。

关于java - Java 中文件存在的锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47508306/

相关文章:

java - 不是一个声明(Java/Android 编译器错误)

java - EMR 版本 4.2.0 上的 Scalding 作业因 VerifyError 而失败

java - karate 如何模拟外部集成 URL

java - 更新文本文件定界符java

c++ - 程序无法打开文件,但文件已经存在

java - java中的同步——new ReentrantLock(true)和new ReentrantLock(false)产生相同的结果?

sql-server-2005 - SQL Server 2005/2008 上的默认表锁定提示

java - 我的登录框架无法链接到我的其他框架

file - Scala - 按文件后缀名从文件夹中删除文件

c++ - C++ 中的多线程多读、少写数组/vector 迭代