5

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

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 与 Seekable Channel。但不确定,为什么删除应该表现不同。
  2. 在较新的实现中,如果在应用程序退出之前它不删除文件,那么它应该返回 false(即不会删除,直到调用 close)或者然后立即删除。

我不知道我是否遇到了错误或遗漏了什么。任何指针都可以提供帮助。

谢谢

4

1 回答 1

1

从规格RandomAccessFile.getChannel()

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

也就是说,返回的通道和通道RandomAccessFile保持双向关系,要么是开放的,要么是封闭的。因此,在这方面,保持锁定状态的不是 ,FileChannel而是RandomAccessFile在通道打开时仍然打开的。File

当您调用close此类时,FileChannel它也会关闭关联RandomAccessFile,让 JRE 中的任何内容都不会阻止delete操作。

相反,在创建FileChannelvia时FileChannel.open,它没有关联FileInputStream的 ,和 ,FileOutputStreamRandomAccessFile不会阻止File.delete操作。

因此,当 JVM/JRE 中没有任何东西阻止该delete操作时,它将表现出底层操作系统的行为,例如 on Microsoft Windows

删除文件功能

删除现有文件。

…</p>

DeleteFile函数将文件标记为在关闭时删除。因此,在文件的最后一个句柄关闭之前,不会发生文件删除。随后调用CreateFile以打开文件失败并显示ERROR_ACCESS_DENIED

这正是观察到的行为。不需要退出JVM,关闭FileChannel即可完成删除。

于 2014-12-03T13:15:15.973 回答