【发布时间】:2016-06-24 20:32:08
【问题描述】:
在调试工作中的问题时,我注意到在将 FileOutputStream 打开到映射文件(通过调用 FileChannel.map() 从中创建 MappedByteBuffer 的文件)后尝试使用 MappedByteBuffer 始终会导致以下异常被抛出:
“线程“主”java.lang.InternalError 中的异常:在不安全的内存访问操作中发生错误”。
这是我拼凑在一起的一个小代码示例,它始终触发异常:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class SomeClass {
// make sure the test file is at least this size, or you'll get a "cannot
// extend file to required size" exception when creating the buffer
private static int bufferSize = 10;
public static void main(String[] args) throws Exception {
File file = new File("/tmp/someFile");
FileInputStream fis = new FileInputStream(file);
ByteBuffer bb = getByteBuffer(fis);
// If you comment this out, the error goes away.
new FileOutputStream(file);
bb.get();
}
private static ByteBuffer getByteBuffer(FileInputStream fis) throws Exception {
return fis.getChannel().map(FileChannel.MapMode.READ_ONLY,
fis.getChannel().position(), bufferSize);
}
}
上述代码始终导致上述异常被抛出。失败发生在“bb.get()”命令上,如果我注释掉打开 FileOutputStream 的代码,则不会发生。
在我看来,错误正在发生,因为我正在调用 .get() 的 ByteBuffer 内存映射到我传递给 FileOutputStream 的同一个文件。我猜有一些内部保护措施可以防止在打开文件时读取内存映射文件,但我无法弄清楚这是什么原因。
当文件上存在打开的 FileOutputStream 时,内存映射的 ByteBuffers 有什么特别之处可以防止读取操作被允许?我对了解这个异常的内部非常感兴趣。让我感到困惑的是,当 FileOutputStream 为同一个文件打开时,打开 FileInputStream 并从中读取似乎没有类似的问题,即使这在功能上应该非常相似(从已经存在的文件中读取)开放写作)。
【问题讨论】:
标签: java operating-system nio mmap bytebuffer