【问题标题】:Expanding Java Memory-Mapped Byte Buffer扩展 Java 内存映射字节缓冲区
【发布时间】:2010-06-12 11:40:32
【问题描述】:

有没有办法扩展 Java 内存映射字节缓冲区,以便将新大小反映回磁盘上的映射文件?

【问题讨论】:

    标签: java expand memory-mapped-files


    【解决方案1】:

    不,您需要调整底层文件的大小并重新创建内存映射字节缓冲区。

    RandomAccessFile file = new RandomAccessFile(/* some file */);
    MappedByteBuffer buffer = file.getChannel().map(MapMode.READ_WRITE, 0, file.length());
    
    // Some stuff happens...
    
    // adjust the size
    file.setLength(newLength);
    
    // recreate the memory mapped buffer
    buffer = file.getChannel().map(MapMode.READ_WRITE, 0, file.length());
    

    注意:设置文件长度有一些奇怪的行为。如果您通过地图在文件末尾之外的特定位置写入文件(使用 map.position() 或 map.putX(position, ...)),则值将附加到文件末尾文件而不是写在您期望的位置(至少在 linux 上)。如果这是不受欢迎的行为,您需要将数据附加到文件中才能真正增大文件。

    【讨论】:

    • 能否请您用其他语言解释一下这种奇怪的行为?如果我写超出文件末尾(通过映射缓冲区假设它映射整个文件大小),是否不希望附加到文件末尾?
    • 从 50 字节大小的文件开始。调用 setLength(1000) 来增加文件的大小。然后从文件 (file.getChannel().map(..., 0, 1000) 创建一个新映射。如果在新的 MappedByteBuffer 上调用 putByte(500, (byte) 'x') 值 'x' 将显示为文件中的第 50 个字节(基于 0 的索引)而不是位置 500(可能并不奇怪,但可能是意外行为)。
    • 我需要关闭缓冲区还是什么?
    • 创建映射缓冲区是一项繁重的任务。如果经常这样做会影响性能吗?
    • @Sohaib 我猜,它和打开文件一样昂贵,或者当您重复使用Channel 时可能更少。所以我认为,“调整”MappedByteBuffer 几次是可以的,但肯定不是每次附加几个字节。通常的问题是没有unmap,当处理太多不同的文件时,您可能会用完文件描述符。仅当缓冲区被 GC'ed 时才会取消映射。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    • 2022-07-15
    相关资源
    最近更新 更多