简短版本:为什么应该 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/