无法读取新锁定的文件

发布于 2024-11-15 09:21:47 字数 1046 浏览 3 评论 0原文

所以我尝试锁定文件来读取它,但我得到了 IOException,知道为什么吗?

public static void main(String[] args){
    File file = new File("C:\\dev\\harry\\data.txt");

    FileReader fileReader = null;
    BufferedReader bufferedReader = null;
    FileChannel channel = null;
    FileLock lock = null;
    try{
        channel  = new RandomAccessFile(file, "rw").getChannel();
        lock = channel.lock();
        fileReader = new FileReader(file);
        bufferedReader = new BufferedReader(fileReader);
        String data;
        while((data = bufferedReader.readLine()) != null){
            System.out.println(data);
        }
    }catch(IOException e){
        e.printStackTrace();
    }finally{
        try {
            lock.release();
            channel.close();
            if(bufferedReader != null) bufferedReader.close();
            if(fileReader != null) fileReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我收到此错误IOException:该进程无法访问该文件,因为另一个进程已锁定文件的一部分

So I try to locked the file to read it, but I got IOException, any idea why?

public static void main(String[] args){
    File file = new File("C:\\dev\\harry\\data.txt");

    FileReader fileReader = null;
    BufferedReader bufferedReader = null;
    FileChannel channel = null;
    FileLock lock = null;
    try{
        channel  = new RandomAccessFile(file, "rw").getChannel();
        lock = channel.lock();
        fileReader = new FileReader(file);
        bufferedReader = new BufferedReader(fileReader);
        String data;
        while((data = bufferedReader.readLine()) != null){
            System.out.println(data);
        }
    }catch(IOException e){
        e.printStackTrace();
    }finally{
        try {
            lock.release();
            channel.close();
            if(bufferedReader != null) bufferedReader.close();
            if(fileReader != null) fileReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

and I got this error IOException: The process cannot access the file because another process has locked a portion of the file

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

指尖上的星空 2024-11-22 09:21:47

不妨将其添加为答案而不是评论。

如果您使用FileLock API,则需要使用相应的NIO文件api。

Might as well add this as an answer instead of a comment.

If you use the FileLock API you need to use the corresponding NIO file apis.

花开雨落又逢春i 2024-11-22 09:21:47

复制我的答案 此处(以防被删除),并添加 Jeff Foster 的反馈:

考虑到抛出了 OverlappingFileLockException 异常的实例,它似乎同一进程中的另一个线程正在尝试锁定同一文件。这不是 A 和 B 之间的冲突,而是 B 内部的冲突,如果查看有关 lock() 方法的 API 文档以及抛出 OverlappingFileLockException 的条件:

如果锁与请求的锁重叠
区域已被该 Java 占用
虚拟机,或者如果另一个线程
已在此方法中被阻止并且
正在尝试锁定重叠的
同一文件的区域

唯一解决方案是阻止 B 中的任何其他线程获取同一文件或文件中同一重叠区域的锁。

抛出的 IOException 有一些更有趣的消息。它可能证实了上述理论,但如果不查看整个源代码,我无法确认任何事情。 lock 方法预计会阻塞,直到获取独占锁。如果获取到了,那么读取文件应该没有问题。除了一个条件。如果文件已由同一 JVM 在不同线程中使用 File 对象(或者换句话说,第二个/不同的文件描述符)打开(并锁定),则对第一个文件描述符的尝试读取将失败,甚至如果获取了锁(毕竟,该锁不会锁定其他线程)。

<罢工>
一种改进的设计是,每个进程中都有一个线程,仅在一定时间内获取文件上的独占锁(当使用单个文件对象或单个文件描述符时),在该文件中执行所需的活动。文件,然后释放锁。

正如 Jeff 所指出的,使用 NIO API 可能会解决问题。这完全是由于 FileReader API 可能打开一个新的文件描述符,该文件描述符与获取锁的文件描述符不同。

Reproducing my answer from here (in case it gets deleted), and adding Jeff Foster's feedback:

Considering that an instance of the OverlappingFileLockException exception is thrown, it appears that another thread in the same process is attempting to lock on the same file. This is not a conflict between A and B, but rather a conflict within B, if one goes by the API documentation on the lock() method and when the condition under which it throws OverlappingFileLockException:

If a lock that overlaps the requested
region is already held by this Java
virtual machine, or if another thread
is already blocked in this method and
is attempting to lock an overlapping
region of the same file

The only solution to prevent this, is to have any other thread in B prevented from acquiring a lock on the same file, or the same overlapping region in the file.

The IOException being thrown has a bit more interesting message. It probably confirms the above theory, but without looking at the entire source code, I cannot confirm anything. The lock method is expected to block until the exclusive lock is acquired. If it was acquired, then there ought to be no problem in reading from the file. Except for one condition. If the file has already been opened (and locked) by the same JVM in a different thread, using a File object (or in other words, a second/different file descriptor), then the attempted read on the first file descriptor will fail even if the lock was acquired (after all, the lock does not lock out other threads).


An improved design, would be to have a single thread in each process that acquires an exclusive lock on the file (while using a single File object, or a single file descriptor) for only a certain amount of time, perform the required activity in the file, and then release the lock.

As Jeff has pointed out, using the NIO APIs would probably result in resolution of the problem. This is entirely due to the possibility of the FileReader API opening a new file descriptor, which is different from the one that the lock is obtained on.

玉环 2024-11-22 09:21:47

也许你想要的更像是:

FileInputStream fis = new FileInputStream(file);
channel = fis.getChannel();
channel.lock();
bufferedReader = new BufferedReader(new InputStreamReader(fis));

Maybe what you want is something more like:

FileInputStream fis = new FileInputStream(file);
channel = fis.getChannel();
channel.lock();
bufferedReader = new BufferedReader(new InputStreamReader(fis));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文