Reputation: 5996
Short version: Why should File.createNewFile()
not be used for file locking? Or more specifically: Are there issues if it is used to lock an applications data directory?
Details:
I would like to protect my applications data directory using a lock file: If the file lock
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 continues. On exit the file will be deleted.
The lock will not be created that often (i.e. performance is not an issue) and I have no problem with manually deleting the lock file in case of some error (i.e. failing to delete the file is not an issue).
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 e.g. 5 times
}
Now I'm a bit confused about the Javadoc of createNewFile()
:
Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist. The check for the existence of the file and the creation of the file if it does not exist are a single operation that is atomic with respect to all other filesystem activities that might affect the file.
Note: this method should not be used for file-locking, as the resulting protocol cannot be made to work reliably. The FileLock facility should be used instead.
What are the potential problems mentioned in the note, considering the existence check and file creation are atomic?
This forum post from December 2007 indicates there are "significant platform differences" according to the Javadoc of File.delete() (although I cannot find such a statement since at least Java SE 1.4.2). But even if there would be such differences: Could they really cause the locking to fail (i.e. two processes think the data directory is usable at the same time)?
Note: I do not want any of the following:
Upvotes: 12
Views: 2014
Reputation: 5996
The Javadoc of 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:
java.nio.file.Files
) is affected by the same (or similar) problems as the older one (from java.io.File
) and the Javadoc is simply missing this information…Given the error handling and specification in java.nio.file
has generally been improved compared to the File
class (existing ever since JDK 1.2), I assume the second alternative is correct.
My conclusion: Using Files.createFile(…)
is fine for this use case.
Upvotes: 2
Reputation: 151
The short answer: reliable file based locking in Java is not practical.
The long answer: The issue with file based locking, in any OS, always comes down to what kind of storage system the file comes from. Almost all network accessed file systems (NFS, SAMBA, etc) have very unreliable (or at least unpredictable) synchronizations on file creates or deletes that make a general Java-ish approach inadvisable. In certain OSes, using local file systems, you can sometimes get what you desire. But you need to understand the underlying file system and its characteristics and proceed with care.
Upvotes: 1