如何在Java中原子重命名文件,即使dest文件已经存在?
我有一个计算机集群,每个计算机运行一个Java应用程序。
这些 Java 应用程序需要同时访问唯一的文件。resource.txt
我需要在Java中原子地重命名文件,即使已经存在。temp.txt
resource.txt
resource.txt
删除和重命名不起作用,因为它不是原子的(它会创建一个不存在的小时间范围)。resource.txt
temp.txt
resource.txt
它应该是跨平台的...
谢谢!
我有一个计算机集群,每个计算机运行一个Java应用程序。
这些 Java 应用程序需要同时访问唯一的文件。resource.txt
我需要在Java中原子地重命名文件,即使已经存在。temp.txt
resource.txt
resource.txt
删除和重命名不起作用,因为它不是原子的(它会创建一个不存在的小时间范围)。resource.txt
temp.txt
resource.txt
它应该是跨平台的...
谢谢!
对于 Java 1.7+,与 CopyOptions 一起使用“REPLACE_EXISTING”和“ATOMIC_MOVE”。java.nio.file.Files.move(Path source, Path target, CopyOption... options)
例如:
Files.move(src, dst, StandardCopyOption.ATOMIC_MOVE);
在Linux上(我相信Solaris和其他UNIX操作系统),Java的File.renameTo()方法将覆盖目标文件(如果存在),但在Windows下不是这种情况。
要成为跨平台,我认为您必须对资源使用文件锁定.txt然后覆盖数据。
文件锁定的行为取决于平台。在某些平台上,文件锁定是建议性的,这意味着除非应用程序检查文件锁定,否则不会阻止它访问该文件。在其他平台上,文件锁定是必需的,这意味着文件锁定会阻止任何应用程序访问该文件。
try {
// Get a file channel for the file
File file = new File("filename");
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
// Use the file channel to create a lock on the file.
// This method blocks until it can retrieve the lock.
FileLock lock = channel.lock();
// Try acquiring the lock without blocking. This method returns
// null or throws an exception if the file is already locked.
try {
lock = channel.tryLock();
} catch (OverlappingFileLockException e) {
// File is already locked in this thread or virtual machine
}
// Release the lock
lock.release();
// Close the file
channel.close();
} catch (Exception e) {
}
默认情况下,Linux使用自愿锁定,而Windows则强制使用它。也许您可以检测到操作系统,并在UNIX下使用debredTo()以及Windows的一些锁定代码?
还有一种方法可以在Linux下为特定文件启用强制锁定,但它有点晦涩难懂。您必须将模式位设置得恰到好处。
Linux,遵循System V(请参阅System V接口定义(SVID)版本3),允许没有组执行权限的文件的sgid位将文件标记为强制锁定