MemoryMappedViewStream.PointerOffset具有错误的值

时间:2017-02-10 23:07:40

标签: c# memory-mapped-files

我在理解MemoryMappedViewStream.PointerOffset属性方面遇到了一些麻烦。在这个简单的单元测试中,我希望流的PointerOffset等于500000但是它是41248.尽管流的长度是10000,所以至少是正确的。 _fakeDataPath是一个100万字节的文件。

    [TestMethod]
    public void CheckViewHasCorrectOffset()
    {
        using (var mmf = MemoryMappedFile.CreateFromFile(_fakeDataPath))
        {
            using (var stream = mmf.CreateViewStream(500000, 10000))
            {
                Assert.AreEqual(500000, stream.PointerOffset);
            }
        }
    }

单位测试输出是......

Assert.AreEqual failed. Expected:<500000>. Actual:<41248>

1 个答案:

答案 0 :(得分:1)

CreateViewStream()是围绕MapViewOfFile() winapi function的.NET包装器。这个api最相关的细节是:

  

高偏移量和低偏移量的组合必须在文件映射中指定偏移量。它们还必须匹配系统的内存分配粒度。也就是说,偏移量必须是分配粒度的倍数。

分配粒度永远是64K。或者换句话说,原生api要求你指定的偏移量必须始终是65536的倍数。

这非常痛苦,他们决定在.NET包装器中隐藏这个限制。很容易完成,他们只需要传递一个不同的偏移量到本机函数,所以它从65536的最接近的对齐倍数开始,小于500000.并使用不同的内部偏移,所以你有效地仍然得到500000.所以你需要修复你的像这样的代码:

  Assert.AreEqual(500000 % 65536, stream.PointerOffset);