Reputation: 452
I'm currently trying to implement a updater for an app I'm writing. The process currently looks as follows:
The problematic part in this process is the file copy of the new release into the app's basedir as some files in the app's base dir may be locked for some reason (i.e. the user opened a file in this dir).
So it could happen that some files have been copied and some haven't - leaving an inconsistent state and possibly not executable app.
What I did to prevent this situation is to check if there's any locked file in the app's basedir prior to copying the new files. I've written a util method for this purpose:
public static boolean isLocked(File pFile){
if (pFile == null || !pFile.exists()){
return false;
}
if (!pFile.canWrite()) return true;
if (!pFile.renameTo(pFile)) return true;
try {
final FileChannel tFileChannel = FileChannel.open(pFile.toPath(), StandardOpenOption.WRITE);
final FileLock tLock = tFileChannel.tryLock();
try {
if (tLock == null){
return true;
} else {
tLock.release();
}
} finally {
tFileChannel.close();
}
} catch (final IOException | OverlappingFileLockException ex) {
return true;
}
return false;
}
But I still think that this process is pretty error-prone as I don't know if the isLocked()
method supplies reliable results under all circumstances.
And even if so, the locked state is only valid at the time the method is called -> the file may be locked immadiately after the call (by an anti-virus scanner for example).
So my question is: Is there is a more reliable way to copy a set of files? Maybe in some kind of rollback-able file transaction?
Upvotes: 2
Views: 66
Reputation: 140467
Maybe i am overlooking something - but isn't the single correct answer to ensure that YOUR updater locked all files before starting its work?
It tries to lock on all files; and only when it "owns" all the relevant files, it starts its work?!
Upvotes: 2