问题

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

澄清:

我有一个Java应用程序,它列出了一个文件夹,并打开列表中的每个文件进行处理。它会逐个处理每个文件。每个文件的处理包括读取它并根据内容进行一些计算,大约需要2分钟。我还有另一个Java应用程序执行相同的操作,而是写入文件。我想要的是能够同时运行这些应用程序,以便场景如下所示。 ReadApp列出文件夹并找到文件A,B,C。它打开文件A并开始读取。 WriteApp列出文件夹并找到文件A,B,C。它打开文件A,看到它是打开的(通过异常或任何方式)并转到文件B. ReadApp完成文件A并继续到B.它看到它是开放的并且继续到C.在ReadApp读取相同文件时WriteApp不写入是至关重要的,反之亦然。它们是不同的过程。


#1 热门回答(96 赞)

FileChannel.lock可能就是你想要的。

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

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

请注意API doc for FileLock中标题为"平台依赖关系"的部分。


#2 热门回答(47 赞)

不要使用java.io包中的类,而是使用java.nio包。后者有一个FileLock类。你可以对aFileChannel应用锁定。

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) {
    }

#3 热门回答(15 赞)

如果你可以使用Java NIO(JDK 1.4或更高版本),那么我认为你正在寻找java.nio.channels.FileChannel.lock()
FileChannel.lock()


原文链接