java nio FileLock.release() 抛出 ClosedChannelException 并截断我的文件

问题描述 投票:0回答:1

我有 e:\myfile.txt,其中包含一些随机内容:

abcabcxyz...abc

然后我尝试使用 nio

FileLock
,如下所示:

import java.io.*;
import java.nio.channels.*;
public class FileLockTest{
    public static void main(String[] args){
        FileLock lock = null;
        try(FileChannel ch=new FileOutputStream(args[0]).getChannel())
        {
            lock=ch.lock();//No param exclusive lock.
            //lock(0L,ch.size(),true) for shared lock.
        }catch(FileNotFoundException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }finally{
            if(lock!=null){
                try{
                    lock.release();//throws exception!
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

运行后我得到:

PS> java FileLockTest e:\myfile.txt
java.nio.channels.ClosedChannelException
        at sun.nio.ch.FileLockImpl.release(Unknown Source)
        at FileLockTest.main(FileLockTest.java:17)

我再次打开myfile.txt,似乎所有内容都丢失了

FileLock
已截断它,对我来说真的很奇怪。

您能帮忙解释一下这里出了什么问题吗?

java nio truncate file-locking
1个回答
3
投票

您的内容丢失,因为您使用输出流以

write
模式而不是
append
打开文件。当以
write
模式打开文件时,先前写入的内容将从文件中删除。在
append
模式下,内容将被保留,任何新写入都会添加到末尾。

在您的情况下,由于您使用的是

FileOutputStream
,因此您需要使用
双参数构造函数 
实例化 ch 并将
true
传递给
append
。否则,流将始终以
write
模式构建。

FileChannel ch = new FileOutputStream(args[0], true)

此外,正如评论中已经说过的,给您

ClosedChannelException
的事实是
FileLock
绑定到已关闭的文件通道。事实上,一旦到达
finally
块,通道就已经关闭,任何释放已关闭通道上的锁的尝试都会失败。

所以,回答你的问题,删除你数据的不是锁,而是你访问文件的方式。此外,由于

FileOutputStream
FileLock
都实现了
AutoClosable
接口,因此您可以将它们都包含在
try-with
语句中,并像这样重写代码:

public static void main(String[] args) {
    try (FileChannel ch = new FileOutputStream(args[0], true).getChannel();
         FileLock lock = ch.lock()) {

        //do your operations....

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.