Moving a directory atomically
You can do this if you use symlinks:
Let's say alpha is a symlink to directory alpha_1, and you want to switch the symlink to point to alpha_2. Here's what that looks like before the switch:
$ ls -l
lrwxrwxrwx alpha -> alpha_1
drwxr-xr-x alpha_1
drwxr-xr-x alpha_2
To make alpha refer to alpha_2, use ln -nsf:
$ ln -nsf alpha_2 alpha
$ ls -l
lrwxrwxrwx alpha -> alpha_2
drwxr-xr-x alpha_1
drwxr-xr-x alpha_2
Now you can remove the old directory:
$ rm -rf alpha_1
Note that this is NOT actually a fully atomic operation, but it does happen very quickly since the "ln" command both unlinks and then immediately recreates the symlink. You can verify this behaviour with strace:
$ strace ln -nsf alpha_2 alpha
...
symlink("alpha_2", "alpha") = -1 EEXIST (File exists)
unlink("alpha") = 0
symlink("alpha_2", "alpha") = 0
...
You can repeat this procedure as desired: e.g. when you have a new version, alpha_3:
$ ln -nsf alpha_3 alpha
$ rm -rf alpha_2
Guaranteed atomic move of folder
If your source and destination paths are on the same filesystem, then mv
is an atomic operation. Since it does not actually involve copying or otherwise relocating files, your directories will never end up in a "half-moved" state.
If, on the other hand, your source and destination paths are on different filesystems, then mv
is actually a copy followed by a delete over the entire tree, which can take a substantial amount of time and, if interrupted, will leave things in a half-completed state.
Atomically move and rename a Path instance
Regarding your first question, since Java 7 you can use Files#move
:
Files.move(path, targetPath);
If you need it to be atomic, you can use the ATOMIC_MOVE
option:
import static java.nio.file.StandardCopyOption.ATOMIC_MOVE;
Files.move(path, targetPath, ATOMIC_MOVE);
Note that:
- this can fail with an
AtomicMoveNotSupportedException
if the option is not supported (for example if you are moving a file from a local hard drive to a network location). - The
REPLACE_EXISTING
option, if used, is ignored and if the target file exists then it is implementation specific if the existing file is replaced or this method fails by throwing anIOException
.
How does one atomically replace a directory with another one in Java?
I am afraid you can't. Not at the SO level at least. So even if you manage "atomicity" in the context of your java application, you have no guarantee about some other "rogue" process interfering at the actual filesystem level.
If I were you, I'd read this article (quite old, but should give you some ideas) and then see if you can port the suggested approach to a more modern version .
Oh, wait, someone did this already!
And apparently your aren't the first one to ask here, either
Best of luck...
Atomicity of File.Move
Yes, in NTFS. From here:
As an aside if you are running under NTFS then file operations are atomic at the file system level. A rename will occur in a single operation as far as any higher code is concerned. The problem you are seeing almost appears to be an issue where the FileInfo object is being shared across applications. It is a MarshalByRef object and therefore can be used in remoting environments. Don't know if this applies to you.
Related Topics
Help with Understanding a Very Basic Main() Disassembly in Gdb
Differencebetween .So and .A Files
Why Is There No Directx API for Linux
Search for a Cronjob with Crontab -L
What Happens to Other Processes When a Docker Container's Pid1 Exits
How to Get Started Writing a Compositing Wm
How to Find or Calculate a Linux Process's Page Table Size and Other Kernel Accounting
How to Setup Oracle Odbc Drivers on Rhel 6/Linux
The Return Code from 'Grep' Is Not as Expected on Linux
Error: Ld.So: Object Ld_Preload Cannot Be Preloaded: Ignored
Difference Between Patch and Diff Files
Bash Script Read All the Files in Directory
How to Close a Netcat Connection After a Certain Character Is Returned in the Response
How to Save Output of "Watch" to File
Where Is Hardware Timer Interrupt
/Proc/$Pid/Maps Shows Pages with No Rwx Permissions on X86_64 Linux