So your Java app is scanning an uploads directory for files that the user will copy in (perhaps via a Windows share). The only snag is that the files can be very large, and you don’t want to start processing a partially uploaded file. What to do?

So, today’s challenge: finding a way to tell if a given File has completed copying to the upload directory or is still in the process of being copied. A colleague pointed me at nio, and we threw together something to get the job done (we already knew that File.exists() and File.canRead(), so your effort may need to be a little more robust than this one, but this will get you started):

   private boolean hasFinishedCopying(File file) {

        FileInputStream fis = null;
        FileLock lock = null;
        try {
            fis = new FileInputStream(file);
            FileChannel fc = fis.getChannel();
            lock = fc.tryLock(0L, Long.MAX_VALUE, true);
        } catch (IOException ioe) {
            return false;
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException ioe) {
                    // give up...
                }
            }
        }
        return lock != null;
    }

The magic you need to be aware of is that third boolean argument to tryLock() on a FileChannel. That says “I want to try to get a shared lock on this file for reading and I under someone else might be writing at the moment”. That’s just my scenario! (And without that shared switch you’ll end up with a NonWritableChannelException).

There’s probably a better way of accomplishing this task, but I thought I would at least blog up one option that we’ve tested to work, so that I can Google this later (since I am sure this is a problem I faced before!).

Happy locking!