为什么当 FileChanel.open() 而不是 RandomAccessFile.getChannel() 获取文件锁时可以移动文件
Why File can be moved when file lock acquired by FileChanel.open() instead of RandomAccessFile.getChannel()
我正在测试 FileChannel.open() 和 RandonAccessFile.getChanel() 获取的 NIO 文件锁。
发现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
的行为也是如此,包括它与明确锁定的文件或以其他方式 "in use" 的文件的交互.
在Windows的情况下,某些文件"open"操作会锁定整个文件,重命名对锁定的文件不起作用。 (事实上 ,我怀疑即使您注释掉 lock()
调用,您使用 getChannel()
的代码版本也会失败。但我没有 Windows 机器来测试它。)
相比之下,Linux 在打开文件时不会锁定文件,并且您可以重命名打开的文件。
如何处理?
如果你想让你的代码跨平台,你需要非常保守。例如,不要尝试重命名您的应用程序当前已打开的文件。重命名前关闭所有文件 "handles"。
或者,编写您的代码以了解平台,并根据需要在不同的平台上做不同的事情。 (我不能准确地告诉你什么,因为你的例子并没有告诉我们你实际想要达到的目标。)
我正在测试 FileChannel.open() 和 RandonAccessFile.getChanel() 获取的 NIO 文件锁。
发现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
的行为也是如此,包括它与明确锁定的文件或以其他方式 "in use" 的文件的交互.
在Windows的情况下,某些文件"open"操作会锁定整个文件,重命名对锁定的文件不起作用。 (事实上 ,我怀疑即使您注释掉 lock()
调用,您使用 getChannel()
的代码版本也会失败。但我没有 Windows 机器来测试它。)
相比之下,Linux 在打开文件时不会锁定文件,并且您可以重命名打开的文件。
如何处理?
如果你想让你的代码跨平台,你需要非常保守。例如,不要尝试重命名您的应用程序当前已打开的文件。重命名前关闭所有文件 "handles"。
或者,编写您的代码以了解平台,并根据需要在不同的平台上做不同的事情。 (我不能准确地告诉你什么,因为你的例子并没有告诉我们你实际想要达到的目标。)