Java 文件锁定和 Windows - 锁定不是“绝对的”?
我正在尝试使用 FileLock 我遇到了一个问题: 锁定文件后,其他进程至少在某种程度上仍然可以访问它。
示例代码如下:
public class SimpleLockExample {
public static void main(String[] args) throws Exception {
String filename = "loremlipsum.txt";
File file = new File(filename);
RandomAccessFile raf = new RandomAccessFile(file, "rw");
FileChannel channel = raf.getChannel();
FileLock lock = null;
try {
lock = channel.tryLock();
String firstLine = raf.readLine();
System.out.println("First line of file : " + firstLine);
waitForEnter();
lock.release();
} catch (OverlappingFileLockException e) {
e.printStackTrace();
}
lock.release();
System.out.println("Lock released");
channel.close();
}
private static void waitForEnter() throws Exception {
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
reader.readLine();
reader.close();
}
}
现在,当我使用此示例锁定我的文件时,它被锁定:
- Windows 无法删除它
- Eclipse 拒绝打开它
...但它仍然不是完全防弹的:
- 如果我用 Scite 打开它(文本编辑器),例如,没有显示任何内容,但如果我选择保存文件(打开时为空或写入了一些内容),它会成功并且文件的内容被清除...(那里不存在任何内容)之后即使我用 Scite 写了一些东西)
是否有某种方法可以完全防止文件被 Windows 中的 Java 的其他进程覆盖/清除?
如果我没理解错的话,我正在使用独占锁atm。使用共享锁可以做更多的事情。
本测试是在 Windows 2000 上运行的
。br, 灯子
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
棘手的是,FileLock API 本身并没有太多承诺:
奇怪的是,有关文件锁定 API 开发时的讨论声称 Windows 操作系统提供强制锁定,而在 Unix 上仅提供建议性锁定。因此,读完这篇文章后,人们可能会期望您的代码在 Windows 上运行得很好。
我想知道是否发生了什么事,您的编辑器不是修改文件而是创建临时文件,然后操作目录条目以便用新版本替换您已锁定的文件版本。 Windows 会允许这种行为吗?
我想知道您是否需要求助于 JNI 以获得所需的控制级别。
Tricky, the FileLock API itself doesn't promise much:
Oddly enough, the discussion about the file locking API when it was under development claimed that Windows OS provided mandatory locking and on Unix only advisory locking. So on that reading one might expect your code to work just fine on Windows.
I wonder if what is happening it that your editor is not so much modifying the file as creating a temporary file and then manipulating directory entries in order to replce the version of the file you have locked with a new version. Would Windows allow such behaviour?
I wonder if you'll need to resort to JNI in order to get the level of control you need.
如果没有获得锁,对 .tryLock() 的调用可能会返回 null。来自 Javadoc:
另外,您的代码当前打开文件,然后它尝试获取锁。相反,您应该循环尝试获取锁定,一旦获得锁定,请打开文件,读取文件,关闭文件,然后放弃锁定。并放弃
finally {}
子句中的锁,以防万一您的代码在持有锁的情况下抛出异常。 (是否曾经因为某些文件被锁定而不得不重新启动 Windows 计算机?)Your call to .tryLock() may return null if it doesn't get the lock. From the Javadoc:
Also, your code currently opens the file and then it tries to acquire a lock. Instead you should loop trying to get the lock, and once you've got it, open the file, read the file, close the file, then give up the lock. And give up the lock in a
finally {}
clause, just in case your code throws an exception with the lock held. (Ever had to reboot a Windows machine just because some file was locked?)