Question

I am using NIO File Channel to manage files, and locking them. So far it works, however when I lock a File using NIO File Lock it locks the file so the file Content cannot be changed. As for example if I try to edit a text file on notepad it will show me the following error message: File Lock

And that is the expected result, however if I try to delete the file from windows explorer(I haven't tested on other OS likely will be possible as well) it will allow me, and this is undesired, I would like to know if it is possible to Open a File Handle

Code Used:

private static final byte[] MessageBytes;
static {
    byte tmp[];
    try {
        tmp = "Hello World".getBytes("UTF-8");
    } catch (UnsupportedEncodingException ex) {
        //if fail get the bytes in whatever the java VM charset sets as default
        tmp = "Hello World".getBytes();
    }
    MessageBytes = tmp;
}
private static final String Filename = "Lock_test.txt";

 private static void createFileandLock() {
    Path FilePath = Paths.get(Filename);
    FileChannel OpenFCh;
    try {
        OpenFCh = FileChannel.open(FilePath, StandardOpenOption.CREATE,
                StandardOpenOption.READ, StandardOpenOption.WRITE
        //                    ,StandardOpenOption.APPEND
        );
        System.out.println("File Channel is Open.");
    } catch (IOException err) {
        OpenFCh = null;
    }
    if (OpenFCh != null) {
        FileLock Lock = null;
        try {
            Lock = OpenFCh.lock();
        } catch (IOException err) {
            System.out.println("Unable To Lock the File.");
        }
        try {
            OpenFCh.write(ByteBuffer.wrap(MessageBytes));
            OpenFCh.force(false);
            System.out.println("Message Recorded");
        } catch (IOException ex) {
            System.out.println("Unable To write data into file");
        }
        try {
            // at this point file still locked and open.
            //lets wait for input and meanwhile ask to delete the file. 
            System.out.print("Please Try to delete file at: ");
            System.out.println(FilePath.toString());
            System.out.println("Press Enter to Continue");
            System.in.read();
        } catch (IOException ex) {
        }
        if (Lock != null) {
            try {
                Lock.close();
            } catch (IOException ex) {
            }
        }
        try {
            OpenFCh.close();
        } catch (IOException ex) {
        }
    }
}

After further research I notice that using RandomAccessFile Will lock the file avoiding deletion as it creates a File Descriptor that basically open a Handle on the underline Operative system. So using the RAF does provide the desired result: File Open Message

Code Used:

private static void createRAFileandLock() {
    RandomAccessFile RAf;
    try {
        RAf = new RandomAccessFile(Filename, "rw");
    } catch (FileNotFoundException ex) {
        //since is open as RW shold not trigger.
        RAf = null;
    }
    if (RAf != null) {
        FileChannel OpenFCh = RAf.getChannel();
        FileLock Lock = null;
        try {
            Lock = OpenFCh.lock();
        } catch (IOException err) {
            System.out.println("Unable To Lock the File.");
        }
        try {
            OpenFCh.write(ByteBuffer.wrap(MessageBytes));
            OpenFCh.force(false);
            System.out.println("Message Recorded");
        } catch (IOException ex) {
            System.out.println("Unable To write data into file");
        }
         // at this point file still locked and open.
        //lets wait for input and meanwhile ask to delete the file. 
        try {
            System.out.print("Please Try to delete file at: ");
            System.out.println(Filename);
            System.out.println("Press Enter to Continue");
            System.in.read();
        } catch (IOException ex) {
        }
        if (Lock != null) {
            try {
                Lock.close();
            } catch (IOException ex) {
            }
        }
        try {
            OpenFCh.close();
            RAf.close();
        } catch (IOException ex) {
        }
    }
}

However I would like to know if it is possible to archive this using only NIO. As Random Access File is on IO package.

Was it helpful?

Solution

FileLock isn't specified to prevent deletion. It's only specified to interact with other file locks, so you're already deep into platform-dependent behaviour. If RandomAccessFile somehow does what you want you may be stuck with it, but you can't rely on it.

NB of course FileChannel.open() uses a FileDescriptor, handle, etc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top