java - java - 如何从使用Java中的FileChannel映射的内存中取消映射文件?

标签 java memory-mapped-files

我正在使用 FileChannel.map() 将文件(“sample.txt”)映射到内存,然后使用 fc.close() 关闭 channel 。之后,当我使用 FileOutputStream 写入文件时,出现以下错误:

java.io.FileNotFoundException: sample.txt (The requested operation cannot be per formed on a file with a user-mapped section open)

File f = new File("sample.txt");
RandomAccessFile raf = new RandomAccessFile(f,"rw");
FileChannel fc = raf.getChannel();
MappedByteBuffer mbf = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
fc.close();
raf.close();

FileOutputStream fos = new FileOutputStream(f);
fos.write(str.getBytes());
fos.close();

我认为这可能是由于即使在我关闭 FileChannel 之后文件仍映射到内存。我对吗?。如果是这样,我怎样才能从内存中“取消映射”文件?(我在 API 中找不到任何方法)。 谢谢。

编辑: 看起来它(添加了一个 unmap 方法)作为 RFE 提交给了 sun 一段时间: http://bugs.sun.com/view_bug.do?bug_id=4724038

最佳答案

可以使用以下静态方法:

public static void unmap(MappedByteBuffer buffer)
{
   sun.misc.Cleaner cleaner = ((DirectBuffer) buffer).cleaner();
   cleaner.clean();
}

但由于以下原因,这是不安全的解决方案:
1) 如果有人在 unmap 之后使用 MappedByteBuffer 会导致失败
2) 它依赖于 MappedByteBuffer 的实现细节

关于java - java - 如何从使用Java中的FileChannel映射的内存中取消映射文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2972986/

相关文章:

java - 如何使用 MySql 维护 Hibernate ID 序列?

java - 反射 - Method::get Generic Return Type no generic - 可见性

c - 系统如何捕获通过 `asm: MOV` 到/从内存映射文件的内存的访问?

c# - MemoryMappedFile 导致下一个 File.Open 需要很长时间

c# - 内存映射文件 IList 实现,用于存储大型数据集 "in memory"?

java - Spring boot AuthenticationSuccessHandler 被忽略

java - 无法使用 Spring 和 JPA 解析映射文件

Java正则表达式删除Freemarker插值标签

c# - 在不知道大小的情况下读取内存映射文件或内存映射 View 访问器的所有内容

c - 如何在 C 中分配和释放对齐内存