防止使用 nio 删除锁定文件

Posted

技术标签:

【中文标题】防止使用 nio 删除锁定文件【英文标题】:Prevent deleting lock file using nio 【发布时间】:2020-12-29 02:05:31 【问题描述】:

我们希望防止其他进程删除我们正在运行的应用程序的临时目录。这样我们就创建了一个临时目录和一个 lock 文件。我发现阻止删除此文件的唯一方法是使用RandomAccessFile

tempDirectory = Files.createTempDirectory("myapp");
final Path lockFile = Files.createTempFile(tempDirectory, "lock", null);
randomAccessFile = new RandomAccessFile(lockFile.toFile(), "rw");

有没有办法用 nio 达到同样的效果?我尝试了以下代码:

import java.io.*;
import java.nio.channels.*;
import java.nio.file.*;

public class CreateLock 

    public static void main(String[] args) throws IOException, InterruptedException 
        final Path path = Paths.get("C:/temp/test");
        Files.createFile(path);
        final FileChannel channel = FileChannel.open(path, StandardOpenOption.WRITE);
        channel.lock();

        for (int i = 60; i-- > 0; ) 
            System.out.println(i);
            if (!Files.isRegularFile(path)) 
                System.out.println("File is gone");
                break;
            

            Thread.sleep(10_000);
        

        channel.close();
    

但第二个 Java 应用程序使用此代码

import java.io.*;
import java.nio.file.*;

public class DeleteLock 

    public static void main(String[] args) throws IOException 
        final Path path = Paths.get("C:/temp/test");
        Files.delete(path);
    

可以删除文件。

【问题讨论】:

那个锁文件的目的是什么?您是否试图控制只有一个应用程序实例正在运行?如果是,我会推荐另一种方式,在您的应用程序中启动时在特定端口上启动一个服务器套接字,比如说 7890,然后监听这个端口。如果用户尝试再次启动您的应用程序,它将失败,因为网络端口正在使用中。 如果您只是保护临时文件夹不被删除,我不明白,为什么需要临时文件夹。尝试删除带有锁定文件的临时文件夹时,可以删除所有未打开的文件(受处理的控制)。并且只有锁定文件将保留在空的临时文件夹中。 @Rafael:我们希望在应用程序运行时保留临时文件夹。我们为什么要这样做不是这个问题的主题。 【参考方案1】:

请尝试以下:

FileChannel ch = FileChannel.open(lockFile.toAbsolutePath(), StandardOpenOption.WRITE);
ch.lock();

【讨论】:

这是我在Win10上试过的。该文件可以删除。

以上是关于防止使用 nio 删除锁定文件的主要内容,如果未能解决你的问题,请参考以下文章

excelvba锁定单元格图片不被删除

创建锁定文件时防止竞争条件

防止多次执行 Lua 脚本

VMware启动报错:另一个程序已锁定文件的一部分,进程无法访问(删除最近的.lck文件夹)

Java NIO基础3文件锁

VMware虚拟机提示“锁定文件失败 打不开磁盘”解决方法