Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

java nio FileLock.release() throws ClosedChannelException and truncates my file

I’ve got e:\myfile.txt with some random contents:

abcabcxyz...abc

Then I try to use nio FileLock like below:

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();
                }
            }
        }
    }
}

Upon running it and I got:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

I open myfile.txt again, all contents are missing, seems
FileLock has truncated it, really strange to me.

Could you help to explain what goes wrong here?

>Solution :

Your content is missing because you’ve accessed your file with an output stream in writing mode which erases all the previous content before performing any writing operation.

If you need to keep the existing content and add new information within your file, then you need to open it in "append" mode by passing a second boolean parameter with value true.

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

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/FileOutputStream.html#%3Cinit%3E(java.lang.String,boolean)

Also, as already said in the comments, what is giving you the ClosedChannelException is the fact that FileLock is bound to a file connection which has been already closed once you’ve exited the try block of your try-with statement. In fact, once you’ve reached your finally block the connection has been closed already and any attempt to release a lock on a closed connection will fail.

So to answer your question, it’s not the lock which erases your data, but rather the way how you access your file. You could rewrite your code like this:

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();
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading