タイトルが示すように、Java 1.6File.renameTo()
では POSIX Linux でのアトミック操作?
このリンクによると、POSIX Linux での名前変更操作はアトミックですが、それは保持true
されFile.renameTo
ますか?
Linux では、ソース パスとターゲット パスが同じマウント ポイント(ファイル システムではない)の下にある場合にのみ、名前の変更はアトミックです。
File.renameTo()
は基本的に Linux での呼び出しrename(2)
であるため、その戻り値をテストして、ファイルの名前を変更できるかどうかを確認する必要があります。
Java 7 では、 を削除File
し、代わりに次を使用します。
Files.move(src, dst, StandardCopyOption.ATOMIC_MOVE);
ここに例があります。私のシステムで/home
は、 は とは異なるマウント ポイント/
であるため、最初の名前変更は成功し (同じファイル システム)、2 回目の名前変更は失敗します。
fge@alustriel:~/tmp/t$ cat Rename.java
import java.io.File;
public final class Rename
{
private Rename()
{
}
public static void main(final String... args)
{
final File f1 = new File("/home/fge/tmp/t/foo");
final File f2 = new File("/home/fge/tmp/t/bar");
final File f3 = new File("/tmp/foo");
if (f1.renameTo(f2))
f2.renameTo(f3);
}
}
fge@alustriel:~/tmp/t$ javac Rename.java
fge@alustriel:~/tmp/t$ strace -ff -o TRACE java Rename
fge@alustriel:~/tmp/t$ grep -w rename TRACE.*
TRACE.17107:rename("/home/fge/tmp/t/foo", "/home/fge/tmp/t/bar") = 0
TRACE.17107:rename("/home/fge/tmp/t/bar", "/tmp/foo") = -1 EXDEV (Invalid cross-device link)