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.

Était-ce utile?

La 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top