java - FileChannel.tryLock 有时会抛出 AccessDeniedException

标签 java nio filelock filechannel

我编写了一个小方法,旨在告诉我应用程序的另一个实例是否已经在运行。我知道有很多方法可以查明另一个实例是否正在运行,但我选择了这个。我正在创建一个空文件,并在应用程序实例的持续时间内将其保持锁定状态。如果另一个实例正在运行,tryLock() 方法应该返回 null:

private static boolean alreadyRunning() throws IOException {
    FileChannel fc = FileChannel.open(MYLOCKFILE,
            StandardOpenOption.CREATE,
            StandardOpenOption.WRITE,
            StandardOpenOption.DELETE_ON_CLOSE);
    return fc.tryLock() == null;
}

(MYLOCKFILE 是我的临时目录中文件的路径。)

在 Windows 7 Professional 64 位上测试此功能时,我发现它对于第一个实例和第二个尝试的实例按预期工作。但是,在第二个实例退出后(只留下第一个实例运行),当运行第三个实例时,tryLock() 调用会抛出 java.nio.file.AccessDeniedException 而不是返回 null。你能解释一下这种行为吗?如果这被认为是正常行为,那么我如何区分文件被锁定的现有实例和真正的“访问被拒绝”情况(例如白痴将 TEMP 目录设置为只读)?

最佳答案

我做了一个测试项目并测试了代码,抛出java.nio.file.AccessDeniedException的唯一问题是代码中使用的StandardOpenOption.DELETE_ON_CLOSE选项。

我删除了该选项,现在工作正常

FileChannel fc = FileChannel.open(MYLOCKFILE, StandardOpenOption.CREATE,
                StandardOpenOption.WRITE);

我认为抛出 java.nio.file.AccessDeniedException 的原因是,一旦您的第二个实例终止选项 StandardOpenOption.DELETE_ON_CLOSE [More explaination] 将尝试在 JVM 退出时删除该文件,如果失败,可能会在内核或操作系统中注册一个事件,以便尽可能删除该文件。因此,如果任何其他进程在删除之前尝试访问、创建或写入同一文件,则会抛出 java.nio.file.AccessDeniedException ,因为该文件的删除操作已挂起。

编辑

根据您的新评论,您可以在检查 alreadyRunning() 代码后放置的 try finally block 中添加以下代码。

片段示例:

        if(!alreadyRunning())
        {
            try
            {
                // YOUR CODE THAT RUNS  
                while(true)
                {
                    //YOUR 
                    Thread.sleep(35000);                        
                }

            }
            finally
            {

                new File("f:\\test.lock").deleteOnExit();               
            }
        }

关于java - FileChannel.tryLock 有时会抛出 AccessDeniedException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34039846/

相关文章:

java - 如何使用 DirectoryStream.Filter 过滤隐藏文件

java - 根据用户操作更改观察者服务

java - Byte[] 用作 BufferInputStream 可以,但是

java - 可点击的 BaseAdapter 行?

java - 使用 SpringBatch 的 ItemReaders 问题读取 S3 资源

java - 在迭代中删除哈希表的元素

java - 如何在安卓上使用文件锁?

java - 在 Java 中,访问 RandomAccessFile 时从 FileChannel 获取 FileLock 的有保证的方法是什么?

windows - 我怎样才能模拟一个 "locked"文件(一个有写锁的文件)

java - 如何开始使用 Java 进行 Web 开发?