我有一组机器,每个机器都运行一个Java应用程序.
这些Java应用程序需要resource.txt
可靠地访问唯一文件.
我需要将temp.txt
文件原子地重命名为resource.txt
Java,即使resource.txt
已经存在.
删除resource.txt
和重命名temp.txt
不起作用,因为它不是原子的(它创建了一个resource.txt
不存在的小时间帧).
它应该是跨平台的......
谢谢 !
对于Java 1.7+,请使用java.nio.file.Files.move(Path source, Path target, CopyOption... options)
CopyOptions"REPLACE_EXISTING"和"ATOMIC_MOVE".
有关更多信息,请参阅API文档.
例如:
Files.move(src, dst, StandardCopyOption.ATOMIC_MOVE);
在Linux上(我相信Solaris和其他UNIX操作系统),Java的File.renameTo()方法将覆盖目标文件(如果存在),但在Windows下不是这种情况.
为了跨平台,我认为你必须在resource.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下使用renameTo()和Windows的一些锁定代码?
还有一种方法可以在Linux下为特定文件打开强制锁定,但它有点模糊.您必须正确设置模式位.
Linux,遵循System V(参见系统V接口定义(SVID)版本3),允许没有组执行权限的文件的sgid位标记文件以进行强制锁定
以下是相关的讨论:http://bugs.sun.com/bugdatabase/view_bug.do?video_id = 4017593