How to atomically replace one directory with another in Java?

I have a directory that contains data files, serve customers say /srv/data. I’m working on a series of updates, /srv/data_tmpand at the end of the operation I would like to atomically replace datawith data_tmp. File.renameTo()always returns false for me when the endpoint is an existing directory. How can i do this?

+5
source share
4 answers

I am afraid you cannot. At least at the SO level. Therefore, even if you control "atomicity" in the context of your Java application, you have no guarantee that some other "rogue" will interfere with the actual level of the file system.

If I were you, I would read this article (quite old, but should give you some ideas), and then see if the proposed approach can be transferred to a more modern version .

Oh wait, someone already is already!

And apparently you are not the first to ask here , either

Good luck ...

+1
source

/srv/data ( Windows XP) . API Java 6, .

NB: .

+1

Linux rename ( rename ), , Java Linux.

+1

" " "", tmp. , , :

mkdir -p tmp/real_dir1 tmp/real_dir2
touch tmp/real_dir1/a tmp/real_dir2/a
# start with ./target_dir pointing to tmp/real_dir1
ln -s tmp/real_dir1 target_dir
# create a symlink named target_dir in tmp, pointing to real_dir2
ln -sf tmp/real_dir2 tmp/target_dir
# atomically mv it into ./ replacing ./target_dir
mv tmp/target_dir ./

An example here is taken from: http://axialcorps.wordpress.com/2013/07/03/atomically-replacing-files-and-directories/

It comes down to (in pseudo-code):

mkdir('./tmp');
mkdir('./tmp/real_dir1');
mkdir('./tmp/real_dir2');
symlink('./tmp/real_dir1', './target_dir')
symlink('./tmp/real_dir2', './tmp/target_dir')
rename('./tmp/target_dir', './target_dir')

The final renaming here is atomic, so the action will either succeed or fail completely, from the point of view of any process using the directory, the action is atomic.

0
source

All Articles