Question

My problem is this: I'm using a WatchService to get notified about new files in a specific folder, now if a file gets moved/copied or created in said folder an event gets triggered and the name of the new file gets returned. The problem now is, if I try to access the file and it is not fully there yet (e.g. the copy is still in progress) an exception gets raised. What i tried was to do something like this:

RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
FileChannel fc = raf.getChannel();
FileLock lck = fc.lock();

But even if a lock gets acquired, sometimes still an Exception gets raised if I try to write to the file because another process has still an open handle to it.

Now, how can a file in Java be locked for truly exclusive access?

Was it helpful?

Solution

For me, the statement

RandomAccessFile raf = new RandomAccessFile(fileName, "rw"); 

returns a FileNotFoundException if I cannot acquire a lock on the file. I catch the filenotfound exception and treat it...

public static boolean isFileLocked(String filename) {
    boolean isLocked=false;
    RandomAccessFile fos=null;
    try {
        File file = new File(filename);
        if(file.exists()) {
            fos=new RandomAccessFile(file,"rw");
        }
    } catch (FileNotFoundException e) {
        isLocked=true;
    }catch (Exception e) {
        // handle exception
    }finally {
        try {
            if(fos!=null) {
                fos.close();
            }
        }catch(Exception e) {
            //handle exception
        }
    }
    return isLocked;
}

you could run this in a loop and wait until you get a lock on the file. Wouldn't the line

FileChannel fc = raf.getChannel();

never reach if the file is locked? You will get a FileNotFoundException thrown..

OTHER TIPS

its better not to use classes in thejava.io package, instead use the java.nio package . The latter has a FileLock class that you can use for a lock to a FileChannel.

try {
        // Get a file channel for the file
        File file = new File("filename");
        FileChannel channel = new RandomAccessFile(file, "rw").getChannel();

        // Use the file channel to create a lock on the file.
        // This method blocks until it can retrieve the lock.
        FileLock lock = channel.lock();

        /*
           use channel.lock OR channel.tryLock();
        */

        // Try acquiring the lock without blocking. This method returns
        // null or throws an exception if the file is already locked.
        try {
            lock = channel.tryLock();
        } catch (OverlappingFileLockException e) {
            // File is already locked in this thread or virtual machine
        }

        // Release the lock - if it is not null!
        if( lock != null ) {
            lock.release();
        }

        // Close the file
        channel.close();
    } catch (Exception e) {
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top