如何使用java锁定文件(如果可能)

2022-08-31 08:27:30

我有一个使用FileReader打开文件的Java进程。如何防止另一个 (Java) 进程打开此文件,或者至少通知第二个进程该文件已被打开?如果文件处于打开状态(这解决了我的问题),这是否会自动使第二个进程出现异常,或者我是否必须在第一个进程中使用某种标志或参数显式打开它?

澄清:

我有一个Java应用程序,它列出了一个文件夹,并打开列表中的每个文件进行处理。它处理每个文件之后的文件。每个文件的处理包括读取它并根据内容进行一些计算,大约需要2分钟。我还有另一个Java应用程序,它做同样的事情,但相反,它写在文件上。我想要的是能够同时运行这些应用程序,因此方案如下所示。ReadApp 列出文件夹并查找文件 A、B、C。它打开文件A并开始读取。WriteApp列出文件夹并查找文件A,B,C。它打开文件A,看到该文件已打开(通过例外或任何方式),然后转到文件B。ReadApp完成文件A并继续到B。它看到它是开放的,并继续到C。至关重要的是,WriteApp在ReadApp读取同一文件时不写入,反之亦然。它们是不同的过程。


答案 1

FileChannel.lock 可能是你想要的。

try (
    FileInputStream in = new FileInputStream(file);
    java.nio.channels.FileLock lock = in.getChannel().lock();
    Reader reader = new InputStreamReader(in, charset)
) {
    ...
}

(免责声明:代码未编译,当然也未经过测试。

请注意 FileLock 的 API 文档中标题为“平台依赖项”的部分。


答案 2

不要使用包中的类,而应使用包 。后者有一个类。您可以将锁应用于 .java.iojava.nioFileLockFileChannel

 try {
        // Get a file channel for the file
        File file = new File("filename");
        FileChannel channel = new RandomAccessFile(file, "rw").getChannel();

        // Use the file channel to create a lock on the file.
        // This method blocks until it can retrieve the lock.
        FileLock lock = channel.lock();

        /*
           use channel.lock OR channel.tryLock();
        */

        // Try acquiring the lock without blocking. This method returns
        // null or throws an exception if the file is already locked.
        try {
            lock = channel.tryLock();
        } catch (OverlappingFileLockException e) {
            // File is already locked in this thread or virtual machine
        }

        // Release the lock - if it is not null!
        if( lock != null ) {
            lock.release();
        }

        // Close the file
        channel.close();
    } catch (Exception e) {
    }