I want to test to see if I can lock file X. If the file doesn't exist or can't be locked, fail. It sounds simple, but I keep running into dead-ends. A short-cut to the answer would be to provide a way to get a FileChannel I can make an exclusive lock on, without any risk of creating a file. Let me explain...
I can't use NIO lock()
without a writable FileChannel and I can't get a writable FileChannel without opening file X in such a way that if it doesn't exist, it is created. Every Java method I've found for trying to open file X as writable creates it if it doesn't exist and there doesn't seem to be a way to exclusively lock a file on a read-only FileChannel.
Even checking to confirm the file exists first is problematic. Here's my latest code:
private LockStatus openAndLockFile(File file) {
if (Files.notExists(file.toPath())) {
synchronized (fileList) {
removeFile(file);
}
return LockStatus.FILE_NOT_FOUND;
}
try {
rwFile = new RandomAccessFile(file, "rw");
fileLock = rwFile.getChannel().lock();
}
catch ...
The problem with this code is that the file might exist when the NotExists
code runs, but be gone by the time the new RandomAccessFile(file, "rw")
runs. This is because I'm running this code in multiple threads and multiple processes which means the code has to be air-tight and rock solid.
Here's an example of the problem with my existing code running in two processes:
1: Process A detects the new file
2: Process B detects the same file
3: Process A processes the file and moves it to another folder
Problem ---> Process B Accidentally creates an empty file. OOPS!!!
4: Process B detects the new file created by process B and processes it creating a duplicate file which is 0 bytes.
5: Process A also detects the new file accidentally created by process B and tries to process it...
Here's an example using C# of what I'm trying to do:
Stream iStream = File.Open("c:\\software\\code.txt", FileMode.Open,
FileAccess.Read, FileShare.None)
Any help or hints are greatly appreciated! Thanks!