Block file existence in Java

Short version: Why is File.createNewFile() not used to lock files? Or more specifically: are there problems if they are used to lock the application data directory?


Details:

I would like to protect the application data directory with a lock file: if the lock file exists, the directory is locked and the application exits with an error message. If it does not exist, it will be created and the application will continue. Upon exit, the file will be deleted.

A lock will not be created often (i.e., performance is not a problem), and I have no problem manually deleting the lock file in case of some error (i.e., I cannot delete the file, this is not a problem).

The code looks something like this:

 File lockFile = new File("lock"); boolean lockCreated = lockFile.createNewFile(); if (lockCreated) { // do stuff lockFile.delete(); } else { System.err.println("Lockfile exists => please retry later"); // alternative: Wait and retry eg 5 times } 

Now I'm a little confused in Javadoc createNewFile() :

Atomically creates a new empty file, called this abstract empty file, if and only if the file with this name does not exist yet. Checking for a file and creating a file if it does not exist is one operation that is atomic with respect to all other file system actions that can affect the file.

Note: this method should not be used to lock files, because the resulting protocol cannot be reliably executed. Instead, use FileLock .

What are the potential problems mentioned in the note, given that existence checking and file creation are atomic?

This forum post from December 2007 indicates that there are “significant platform differences” according to Javadoc File.delete () (although I cannot find such an operator with at least Java SE 1.4.2). But even if there were such differences: could they really cause the lock to fail (i.e., two processes believe that the data directory can be used simultaneously)?


Note: I do not want any of the following:

  • Lock the file so that no other process can access and / or modify it (most of the data found seem to discuss this problem).
  • Verify that another process cannot remove the lock.
  • Synchronize multiple threads with the same JVM (although I think my solution can handle this too).
+7
java file locking
source share
2 answers

Short answer: robust file-based locking in Java is not practical.

Long answer: the problem with file-based locking in any OS always comes down to which storage system the file comes from. Almost all network file systems (NFS, SAMBA, etc.) have very unreliable (or at least unpredictable) synchronization in the file, create or delete, which makes the general Java-ish approach unacceptable. On some operating systems, using local file systems, you can sometimes get what you want. But you need to understand the main file system and its characteristics and act carefully.

+1
source share

Javadoc Files.createFile(…) , part of java.nio.file , available since Java 7, repeats the promise of atomicity, but does not mention anything about file-based locking.


My reasoning is:

  • The new method (from java.nio.file.Files ) is affected by the same (or similar) problems as the older one (from java.io.File ), and Javadoc simply skips this information ...
  • ... or a newer method does behave more predictably and correctly.

Given that the error handling and specification in java.nio.file were generally improved over the File class (existing with JDK 1.2), I assume that the second option is correct.


My conclusion: using Files.createFile(…) is suitable for this use case.

+1
source share

All Articles