Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to lock Files to avoid deletion using NIO package

Tags:

java

windows

nio

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.

like image 518
Sith Nazgûl Cat Avatar asked May 10 '14 05:05

Sith Nazgûl Cat


People also ask

How would you avoid accidentally removing files?

Almost all modern file managers (Windows, macOS, Linux GUIs) come with a “trash can”. When you “delete” a file or folder, it doesn't get removed instantly, but rather gets moved to the trash. This acts as a safety net against accidental deletion.

How do I stop deleting a folder?

Right-clik the folder and select Properties. On the Security tab, select Advanced. On the Permissions tab, Disable inheritance, removing all inherited permissions. This denies permission to do anything to that folder, until you assign an owner and set permissions for that owner.

How do you lock a file in Java?

In Java, a file lock can be obtained using FileChannel , which provides two methods — lock() and tryLock() — for this purpose. The lock() method acquires an exclusive lock on entire file, whereas the lock(long position, long size, boolean shared) method can be used to acquire a lock on the given region of a ile.


1 Answers

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.

like image 129
user207421 Avatar answered Sep 19 '22 03:09

user207421