RandomAccessFile对NIO频道

时间:2014-12-02 11:36:17

标签: java java-7 nio java-io filechannel

我试图了解以下行为。我的旧代码,

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()”,它会立即将其删除。

几个问题,

  1. 为什么不同的行为,我理解两者都是不同的类型,即RA vs Seekable Channel。但不确定,为什么删除应该有不同的行为。
  2. 在较新的实现中,如果它不删除文件,直到应用程序退出,那么它应该返回false(即不会删除,直到关闭被调用)或者然后立即删除。
  3. 我不知道我是否遇到了错误或遗漏了什么。任何指针都可以提供帮助。

    由于

1 个答案:

答案 0 :(得分:1)

来自RandomAccessFile.getChannel()的规范:

  

返回通道的位置始终等于getFilePointer方法返回的此对象的文件指针偏移量。无论是显式地还是通过读取或写入字节,更改此对象的文件指针偏移量都将改变通道的位置,反之亦然。通过此对象更改文件的长度将更改通过文件通道看到的长度,反之亦然。

换句话说,返回的通道和RandomAccessFile保持双向关系,并且两者都是打开或关闭的。所以在这方面,它不是FileChannel,而是RandomAccessFile,它在通道打开时仍处于打开状态,可以使File锁定。

当您在close上致电FileChannel时,它也会关闭相关的RandomAccessFile,让JRE中没有任何内容阻止delete操作。

相反,在通过FileChannel创建FileChannel.open时,它没有关联的FileInputStreamFileOutputStreamRandomAccessFile,并且不会阻止File.delete操作。

因此,当JVM / JRE中没有任何内容阻止delete操作时,它将展示底层操作系统的行为,例如:在Microsoft Windows

  

DeleteFile function

     

删除现有文件。

     

...

     

DeleteFile 功能会在关闭时标记要删除的文件。因此,在关闭文件的最后一个句柄之前不会发生文件删除。通过 ERROR_ACCESS_DENIED CreateFile打开文件的后续调用失败。

这正是观察到的行为。您无需退出JVM,关闭FileChannel就足以完成删除。