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:
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:
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With