我正在尝试使用FileLock在Windows环境中使用Java锁定文件,我遇到了一个问题: 在我锁定文件后,至少在某个级别上,其他进程仍然可以访问它。
示例代码如下:
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中的其他Java进程覆盖/清除?
如果我理解正确,我正在使用独占锁定atm。使用共享锁可以完成更多的事情。
此测试是在Windows 2000上运行的。
BR, Touko
答案 0 :(得分:5)
Tricky,FileLock API本身并没有多少承诺:
此文件锁定API旨在 直接映射到本机锁定 基础经营的设施 系统。因此锁定在文件上 应该对所有程序都可见 无论如何都可以访问该文件 这些程序的语言 写的。
是否实际锁定 防止其他程序 访问锁定的内容 区域是系统依赖的 因此未指明。本土的 一些文件锁定设施 系统只是建议,意思 程序必须合作 观察已知的锁定协议 为了保证数据的完整性。上 其他系统本机文件锁是 强制性,意味着如果一个程序 锁定文件的区域,然后锁定其他区域 实际上阻止了程序 以某种方式访问该区域 会违反锁定。还有一点 系统,无论是本机文件锁 咨询或强制性是可配置的 在每个文件的基础上。确保 一致和正确的行为 平台,强烈推荐 这个API提供的锁是 就像他们是咨询锁一样。
奇怪的是,关于文件锁定API的讨论在开发时声称Windows操作系统提供了强制锁定,而在Unix上只提供了建议锁定。因此,在阅读时,人们可能希望您的代码在Windows上运行良好。
我想知道发生了什么事情,你的编辑器并没有像创建一个临时文件那样修改文件,然后操纵目录条目来重新复制你用新版本锁定的文件版本。 Windows会允许这样的行为吗?
我想知道你是否需要求助于JNI以获得所需的控制水平。
答案 1 :(得分:1)
如果没有获得锁定,您对.tryLock()的调用可能会返回null。来自Javadoc:
表示新获取的锁的锁对象,如果由于另一个程序持有重叠锁而无法获取锁,则返回null
此外,您的代码当前打开文件,然后它尝试获取锁定。相反,你应该循环尝试获取锁定,一旦你得到它,打开文件,读取文件,关闭文件,然后放弃锁定。并放弃finally {}
子句中的锁定,以防您的代码在锁定时抛出异常。 (曾经因为某些文件被锁定而不得不重新启动Windows机器?)