我试图了解以下行为。我的旧代码,
String path = "C:/temp/sample.txt";
String mode= "rw";
FileChannel channel = new RandomAccessFile(path, mode).getChannel();
// some code to write to this file
// finally delete
File file = new File(path);
boolean isDeleted = file.delete();
System.out.println("Is Deleted - " + isDeleted);
O / P - 已删除 - 错误
只有我做了“channel.close();”在我删除文件之前。它是否删除该文件并返回true。
更新的代码,
String path = "C:/temp/sample.txt";
FileChannel fChannel = FileChannel.open(path, StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
// some code to write to this file
// finally delete
File file = new File(path);
boolean isDeleted = file.delete();
System.out.println("Is Deleted - " + isDeleted);
O / P - 已删除 - 是
但是在应用程序退出之前,这不会删除文件。如果我使用“fChannel.close()”,它会立即将其删除。
几个问题,
我不知道我是否遇到了错误或遗漏了什么。任何指针都可以提供帮助。
由于
答案 0 :(得分:1)
来自RandomAccessFile.getChannel()
的规范:
返回通道的位置始终等于getFilePointer方法返回的此对象的文件指针偏移量。无论是显式地还是通过读取或写入字节,更改此对象的文件指针偏移量都将改变通道的位置,反之亦然。通过此对象更改文件的长度将更改通过文件通道看到的长度,反之亦然。
换句话说,返回的通道和RandomAccessFile
保持双向关系,并且两者都是打开或关闭的。所以在这方面,它不是FileChannel
,而是RandomAccessFile
,它在通道打开时仍处于打开状态,可以使File
锁定。
当您在close
上致电FileChannel
时,它也会关闭相关的RandomAccessFile
,让JRE中没有任何内容阻止delete
操作。
相反,在通过FileChannel
创建FileChannel.open
时,它没有关联的FileInputStream
,FileOutputStream
和RandomAccessFile
,并且不会阻止File.delete
操作。
因此,当JVM / JRE中没有任何内容阻止delete
操作时,它将展示底层操作系统的行为,例如:在Microsoft Windows
:
DeleteFile function
删除现有文件。
...
DeleteFile 功能会在关闭时标记要删除的文件。因此,在关闭文件的最后一个句柄之前不会发生文件删除。通过 ERROR_ACCESS_DENIED 对CreateFile打开文件的后续调用失败。
这正是观察到的行为。您无需退出JVM,关闭FileChannel
就足以完成删除。