.NET 4.0 Framework引入了用于读取和写入内存映射文件的类.这些类以读取和写入结构的方法为中心.这些不是编组的,而是以它们在托管内存中布局的形式从文件复制到文件.
假设我想使用以下方法将两个结构顺序写入内存映射文件:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct Foo
{
public char C;
public bool B;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct Bar
{
}
static void Write<T1, T2>(T1 item1, T2 item2)
where T1 : struct
where T2 : struct
{
using (MemoryMappedFile file = MemoryMappedFile.CreateNew(null, 32))
using (MemoryMappedViewAccessor accessor = file.CreateViewAccessor())
{
accessor.Write<T1>(0L, ref item1); // <-- (1)
accessor.Write<T2>(??, ref item2); // <-- (2)
}
}
static void Main()
{
Foo foo = new Foo { C = '?', B = true };
Bar bar = new Bar { };
Write(foo, bar);
}
Run Code Online (Sandbox Code Playgroud)
如何获得(1)中写入的字节数,以便在(2)中相邻写入下一个值?
注意:示例中的字节数为3(= 2 + 1),而不是Marshal.SizeOf返回的5(= 1 + 4).
注2:sizeof无法确定泛型类型参数的大小.
似乎没有记录/公共的方法来访问SizeOfType类使用的内部函数MemoryMappedViewAccessor,因此获取这些结构的大小的最实用的方法是使用像这样的反射:
static readonly Func<Type, uint> SizeOfType = (Func<Type, uint>)Delegate.CreateDelegate(typeof(Func<Type, uint>), typeof(Marshal).GetMethod("SizeOfType", BindingFlags.NonPublic | BindingFlags.Static));
static void Write<T1, T2>(T1 item1, T2 item2)
where T1 : struct
where T2 : struct
{
using (MemoryMappedFile file = MemoryMappedFile.CreateNew(null, 32))
using (MemoryMappedViewAccessor accessor = file.CreateViewAccessor())
{
accessor.Write(0, ref item1);
accessor.Write(SizeOfType(typeof(T1)), ref item2);
}
}
Run Code Online (Sandbox Code Playgroud)