【问题标题】:Reading from a java.nio.MappedByteBuffer when a FileOutputStream is open for the mapped file causes an "unsafe memory access" error为映射文件打开 FileOutputStream 时从 java.nio.MappedByteBuffer 读取会导致“不安全的内存访问”错误
【发布时间】: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


    【解决方案1】:

    当您创建内存映射时,您将文件的一个区域映射到内存中。

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

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

    【讨论】:

    • 你说得对——这绝对是正在发生的事情。我做了另一个快速测试,将“追加”标志传递给 FileOutputStream,问题不再发生。
    猜你喜欢
    • 2014-01-24
    • 1970-01-01
    • 2014-02-12
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多