繁体   English   中英

当为映射文件打开FileOutputStream时,从java.nio.MappedByteBuffer读取会导致“不安全的内存访问”错误

[英]Reading from a java.nio.MappedByteBuffer when a FileOutputStream is open for the mapped file causes an “unsafe memory access” error

在调试工作中的问题时,我注意到在打开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的同一文件。 我猜想有一些内部保护措施可以防止在打开文件时读取内存映射文件,但是我无法弄清楚这是什么原因。

内存映射的ByteBuffer有什么特殊之处,可以防止文件上存在打开的FileOutputStream时允许读取操作? 我对了解此异常的内部非常感兴趣。 同样使我感到困惑的是,即使为相同文件打开FileOutputStream时,打开FileInputStream并从中读取似乎也没有类似的问题,尽管这在本质上应该非常相似(从已经存在的文件中读取)开放写作)。

创建内存映射时,您正在将文件区域映射到内存中。

使用FileOutputStream时,将截断文件,并且映射的内存区域不再存在。

如果不截断文件,它将具有执行映射时指定的大小。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM