【问题标题】:Java file locking and Windows - the lock isn't "absolute"?Java 文件锁定和 Windows - 锁定不是“绝对的”?
【发布时间】:2009-08-27 06:58:49
【问题描述】:

我正在尝试使用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 无法删除它
  • Eclipse 拒绝打开它

...但它仍然不是完全防弹的:

  • 如果我用 Scite(文本编辑器)打开它,例如,没有显示内容,但如果我选择保存文件(打开时为空或写入一些内容),它会成功并且文件的内容是清除...(即使我用 Scite 写了一些东西,也没有内容存在)

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

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

此测试是在 Windows 2000 上运行的。

br, 图子

【问题讨论】:

    标签: java windows filelock


    【解决方案1】:

    棘手,FileLock API 本身并没有太多承诺:

    此文件锁定 API 旨在 直接映射到本机锁定 基础运营设施 系统。因此,文件上的锁 应该对所有程序可见 有权访问该文件,无论 这些程序使用的语言 都写好了。

    实际上是否有锁 防止另一个程序 访问锁定的内容 区域依赖于系统并且 因此未指定。本地人 一些文件锁定设施 系统只是建议性的,意思是 该计划必须合作 观察一个已知的锁定协议 以保证数据的完整性。在 其他系统本机文件锁是 强制性的,这意味着如果一个程序 锁定文件的一个区域,然后锁定其他区域 程序实际上是被阻止的 以某种方式访问​​该区域 会违反锁。在另一个 系统,本机文件锁是否 建议或强制是可配置的 在每个文件的基础上。确保 一致和正确的行为 平台,强烈推荐 该 API 提供的锁是 就像它们是咨询锁一样使用。

    奇怪的是,关于文件锁定 API 在开发时的讨论声称 Windows 操作系统提供强制锁定,而在 Unix 上仅提供咨询锁定。因此,在阅读时,您可能希望您的代码在 Windows 上运行良好。

    我想知道你的编辑器不是在修改文件而是创建一个临时文件然后操作目录条目以用新版本替换你锁定的文件版本是怎么回事。 Windows 会允许这种行为吗?

    我想知道您是否需要借助 JNI 来获得所需的控制级别。

    【讨论】:

      【解决方案2】:

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

      表示新获得的锁的锁对象,如果由于另一个程序持有重叠锁而无法获得锁,则为 null

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

      【讨论】:

      • 如何在打开文件之前获得锁?您不需要文件来调用 getChannel 吗?
      猜你喜欢
      • 1970-01-01
      • 2021-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      • 2020-01-12
      • 2015-10-18
      相关资源
      最近更新 更多