使用 MemoryMappedFile 作为 BinaryReader

Use MemoryMappedFile as BinaryReader

我正在使用 MemoryMappedFile(MMF) 将大文件放入内存。使用内存限制 32MB。使用 MMF 加载 50MB 文件需要 2-3 秒。从 MMF 读取数据工作正常且快速。 对我来说唯一的问题是:我有一个大项目,在多个地方大量使用 BigEndianReader(派生自 BinaryReader)。与其重写代码,我更喜欢修改此 class 以将 BinaryReader 调用替换为 MMF 调用。有人知道如何从 MMF 创建 strteam 吗?我有 MMF 的 IntPtr,但我不明白如何从中创建 Stream。

您必须子class Stream,跟踪流的 Position 和当前映射的片段:

public class MmfStream : Stream
{
    private IntPtr currentMap;
    private long mapOffset;
    private long mapSize;
    private long position;

Stream 基础 class 要求您实现 ReadWrite 方法,因此每当应用程序尝试读取或写入时,您都可以使用 Marshal.Copy 从当前映射段复制数据。

如果流的 Position 超出映射段,您将创建一个新映射并提供来自新映射段的信息。您还必须处理必须从当前 新映射的视图访问数据的问题。类似于:

public override int Read(byte[] buffer, int offset, int size)
{
    // current position not in current mapping?
    if (position < mapOffset)
    {
        // relocate the view
    }

    // compute how many bytes can be read from the current segment
    int read = Math.Min(size, (mapOffset + mapSize) - position);

    // copy those bytes to the buffer
    Marshal.Copy(...);

    position += read;

    if (size > read)
    {
        // recurse for the remaining bytes
        read += Read(buffer, offset + read, size - read);
    }

    return read;
}

(此代码片段中可能存在一次性错误;这只是对想法的说明)