Details
-
Improvement
-
Status: Closed
-
Trivial
-
Resolution: Information Provided
-
None
-
None
-
None
-
None
Description
Looking at current openjdk (11) source code, the regular File.rename() method calls the standard native rename function on UNIX-like systems. At least on Linux, this allows me to (atomically?) replace a file with another one, ie. without deleting the target file first.
FileUtils.moveFile however, throws an exception in case the target file alrady exists.
Here is the code bloat I currently use to rename-overwrite a file (and which I want to get rid of):
// try to rename atomically first try { if (!tempFile.renameTo(mdFile)) { throw new IOException(); } } catch (Exception ex) { // then explicitly delete the target file first if (mdFile.exists()) { mdFile.delete(); } if (!tempFile.renameTo(mdFile)) { throw new IOException("failed to rename " + tempFile + " to " + mdFile); } }
Can we please have a function that force-fully replaces existing target files, first atomically, then falling back to delete and move? Maybe call it FileUtils.forceRenameTo and don't delete target directories, only target files.
It could be simply a modification of the existing moveFile function: remove check for existing target, check and throw exception only if it is a directory. Then, upon moving, catch the exception and check if it could be due to existing target file. If so, retry after manually removing the target file.
Also, having a function with proper fsync support would be nice in that context: https://stackoverflow.com/questions/7433057/is-rename-without-fsync-safe
FielUtils.syncRenameTo?