Java文件锁定和Windows - 锁不是“绝对的”?

时间:2009-08-27 06:58:49

标签: java windows filelock

我正在尝试使用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, Touko

2 个答案:

答案 0 :(得分:5)

Tricky,FileLock API本身并没有多少承诺:

  

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

     

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

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

我想知道发生了什么事情,你的编辑器并没有像创建一个临时文件那样修改文件,然后操纵目录条目来重新复制你用新版本锁定的文件版本。 Windows会允许这样的行为吗?

我想知道你是否需要求助于JNI以获得所需的控制水平。

答案 1 :(得分:1)

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

  

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

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