java - 为什么 FileChanel.open() 而不是 RandomAccessFile.getChannel() 获得文件锁时可以移动文件
问题描述
我正在测试 FileChannel.open() 和 RandonAccessFile.getChanel() 获取的 NIO File Lock。
发现FileChannel.open()获取的FileLock可以移动,而RandonAccessFile.getChanel()获取的FileLock不能移动。
FileChannel.open()
File file = new File("../tmp/test.txt");
FileChannel fileChannel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE);
FileLock fileLock = fileChannel.lock();
System.out.println("file locked");
boolean result = file.renameTo(new File("../tmp/test2.txt"));
System.out.println("rename result " + result);
fileLock.release();
fileChannel.close();
RandonAccessFile.getChanel()
File file = new File("../tmp/test.txt");
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rws");
FileChannel newChannel = (randomAccessFile).getChannel();
FileLock fileLock = newChannel.lock();
System.out.println("File locked");
boolean result = file.renameTo(new File("../tmp/test2.txt"));
System.out.println("rename result " + result);
解决方案
Java 文件锁的行为是高度特定于平台的, 的行为也是如此renameTo
,包括它与显式锁定或以其他方式“使用”的文件的交互。
在 Windows 的情况下,某些文件“打开”操作会锁定整个文件,而重命名对锁定的文件不起作用。(实际上,我怀疑getChannel()
即使您注释掉了lock()
调用,您使用的代码版本也会失败。但我没有 Windows 机器来测试它。)
相比之下,Linux 在打开文件时不会锁定文件,您可以重命名打开的文件。
如何处理?
如果你希望你的代码是跨平台的,你需要非常保守。例如,不要尝试重命名您的应用程序当前已打开的文件。在重命名之前关闭所有文件“句柄”。
或者,编写代码以了解平台,并根据需要在不同平台上做不同的事情。(我不能确切地建议什么,因为你的例子并没有告诉我们你实际想要达到的目标。)
推荐阅读
- autohotkey - AutoHotKey 无法识别 AltGr+Alt+Y
- php - 如何在一行中显示返回的条目,用逗号或另一个字符分隔
- python - 什么是 alexnet 权重结构,如何将其加载到我的模型中?
- c++ - 整数溢出和 std::stoi
- angular - 如何测试一个简单的 Angular 响应式表单
- javascript - 使用 Fetch 返回 GitHub 用户数据
- php - 我如何将几个确定的整数位设置为具体值?
- r - 从 R 中的在线“下载 .csv”按钮获取 .csv 数据
- javascript - 从 Puppeteer 浏览器/页面上下文中提取本机界面
- python - vscode 在 docker 实例中运行/调试 python