java - 如果文件存在,如何锁定它而不创建它?

标签 java multithreading locking filechannel

我想测试一下是否可以锁定文件X。如果该文件不存在或无法锁定,则失败。听起来很简单,但我总是陷入死胡同。解决这个问题的捷径是提供一种方法来获取 FileChannel,我可以对其进行独占锁定,而无需任何创建文件的风险。让我解释一下...

如果没有可写的 FileChannel,我就无法使用 NIO lock(),并且如果不打开文件 X,我就无法获得可写的 FileChannel,如果文件 X 不存在,则它是创建的。我发现的每个试图以可写方式打开文件 X 的 Java 方法都会在文件 X 不存在时创建它,并且似乎没有一种方法可以独占锁定只读 FileChannel 上的文件。

即使先检查以确认文件是否存在也是有问题的。这是我的最新代码:

private LockStatus openAndLockFile(File file) {

            if (Files.notExists(file.toPath())) {
                synchronized (fileList) {
                    removeFile(file);
                }
                return LockStatus.FILE_NOT_FOUND;
            }
            try {   
                rwFile = new RandomAccessFile(file, "rw");
                fileLock = rwFile.getChannel().lock();                  
            } 
            catch ...

此代码的问题在于,当 NotExists 代码运行时,该文件可能存在,但在 new RandomAccessFile(file, "rw") 时消失运行。这是因为我在多个线程和多个进程中运行此代码,这意味着代码必须是无懈可击且坚如磐石的。

以下是我的现有代码在两个进程中运行时出现的问题的示例:

1:进程A检测到新文件

2:进程B检测到同一个文件

3:进程A处理文件并将其移动到另一个文件夹

问题 ---> 进程 B 意外创建了一个空文件。哎呀!!!

4:进程B检测到进程B创建的新文件并处理它,创建一个0字节的重复文件。

5:进程A还检测到进程B意外创建的新文件并尝试处理它...

Bigger screenshot

/image/cHlsJ.png

这是一个使用 C# 的示例,说明我正在尝试执行的操作:

Stream iStream = File.Open("c:\\software\\code.txt", FileMode.Open,
    FileAccess.Read, FileShare.None)

非常感谢任何帮助或提示!谢谢!

最佳答案

如果您试图阻止同一应用程序(同一 JVM)中的两个线程处理同一文件,那么您应该使用常规 Java 锁而不是文件锁来实现此目的。文件锁被授予 JVM 并且是可重入的……因此,如果一个线程“锁定”一个文件,另一个线程就可以获得同一文件上的锁。

我要做的是创建一个线程安全的锁定类来包装 HashSet<File> ,其中File对象表示存在的文件的绝对文件路径。然后通过锁定 File 来实现“文件锁定”对象。

<小时/>

Unfortunately not only will they be in different JVMs, they will sometimes be on different server.

在这种情况下,最好的策略可能是使用数据库来实现锁。

关于java - 如果文件存在,如何锁定它而不创建它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30554230/

相关文章:

java - XML-BEANS 编译模式 : Could not locate compiled schema resource schemaorg_apache_xmlbeans/system/sE130CAA0A01A7CDE5A2B4FEB8B311707/index. xsb

java - jar 的 URL 问题

c++ - 如何识别导致Qt 警告信息的行?

java - 如何使用 JPA 释放锁定的行?

java - 了解二进制搜索错误

java - 使用Java绘图: Applying Borders/Outlines to Shapes

java - 高并发写入数据库

C# 线程 - 锁定对象

c# - 文件上传 60 分钟后启动线程进程

java - Spring 原型(prototype)引用 Singleton