Java文件locking和Windows – 锁不是“绝对”?

我试图用FileLock在Windows环境中用Javalocking一个文件,我得到了一个问题:在我locking文件后,至less在某个级别上仍然可以被其他进程访问。

示例代码如下:

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(); } } 

现在,当我用这个例子locking我的文件时,它被locking了:

  • 它不能被Windows删除
  • Eclipse拒绝打开它

…但这并不完全是防弹的:

  • 例如,如果我用Scite(文本编辑器)打开它,则不显示任何内容,但是如果select保存文件(打开时为空或写入某些内容),则成功并清除文件内容。 (之后没有内容存在,即使我用Scite写了一些东西)

有什么办法可以防止文件完全被Windows中的Java的其他进程覆盖/清除?

如果我理解正确,我使用独占锁atm。 共享锁有更多的事情可以做。

这个testing是在Windows 2000上运行的。

br,Touko

狡猾,FileLock API本身不承诺太多:

这个文件锁定API旨在直接映射到底层操作系统的本机锁定工具。 因此,无论程序写入的语言如何,文件上的锁应该对所有有权访问该文件的程序都可见。

锁是否实际上阻止另一个程序访问锁定区域的内容是依赖于系统的,因此是未指定的。 某些系统的本机文件锁定功能仅仅是建议性的,这意味着程序必须协作地观察已知的锁定协议以保证数据的完整性。 在其他系统上,本地文件锁定是强制性的,这意味着如果一个程序锁定文件的某个区域,则实际上阻止其他程序以违反该锁定的方式访问该区域。 在其他系统上,本地文件锁是建议性的还是强制性的,可以在每个文件的基础上配置。 为了确保跨平台的一致和正确的行为,强烈建议使用由此API提供的锁,就好像它们是咨询锁一样。

奇怪的是,关于正在开发的文件锁定API的讨论声称,Windows操作系统提供了强制锁定,并且在Unix上只有通知锁定。 所以在阅读上,你可能会希望你的代码在Windows上工作得很好。

我不知道是否发生了什么事情,你的编辑器没有那么多修改文件创建一个临时文件,然后操纵目录条目,以replce你已经锁定一个新版本的文件的版本。 Windows会允许这种行为吗?

我想知道你是否需要使用JNI来获得你需要的控制级别。

对.tryLock()的调用如果没有获得锁,则可能会返回null。 从Javadoc:

表示新获取的锁的锁对象;如果由于另一个程序存在重叠的锁而无法获取锁,则为null

此外,您的代码当前打开文件,然后尝试获取一个锁。 相反,你应该循环试图获得锁,一旦你得到它,打开文件,读取文件,关闭文件,然后放弃锁。 并放弃在finally {}子句中的锁,以防万一您的代码抛出一个异常与持有锁。 (曾经因为某个文件被锁定而不得不重启Windows机器?)