内存映射文件分为两种类型:
-
持久化内存映射文件
持久化文件是与磁盘上的源文件相关联的内存映射文件。 当最后一个进程处理完文件时,数据保存到磁盘上的源文件中。 此类内存映射文件适用于处理非常大的源文件。
-
非持久化内存映射文件
非持久化文件是不与磁盘上的文件相关联的内存映射文件。 当最后一个进程处理完文件时,数据会丢失,且文件被垃圾回收器回收。 此类文件适合创建共享内存,以进行进程内通信 (IPC)。
进程、视图和管理内存
可以跨多个进程共享内存映射文件。 进程可以映射到相同的内存映射文件,只需使用文件创建进程分配的通用名称即可。
必须创建整个或部分内存映射文件的视图,才能使用内存映射文件。 还可以为内存映射文件的同一部分创建多个视图,从而创建并发内存。 若要让两个视图一直处于并发状态,必须通过同一个内存映射文件创建它们。
如果文件大于可用于内存映射的应用逻辑内存空间(在 32 位计算机中为 2GB),可能也有必要使用多个视图。
视图分为以下两种类型:流访问视图和随机访问视图。 使用流访问视图,可以顺序访问文件;建议对非持久化文件和 IPC 使用这种类型。 随机访问视图是处理持久化文件的首选类型。
由于内存映射文件是通过操作系统的内存管理程序进行访问,因此文件会被自动分区到很多页面,并根据需要进行访问。 无需自行处理内存管理。
持久化内存映射文件
CreateFromFile 方法通过磁盘上的现有文件创建内存映射文件。
using System; using System.IO; using System.IO.MemoryMappedFiles; using System.Runtime.InteropServices; class Program { static void Main(string[] args) { long offset = 0x10000000; // 256 megabytes long length = 0x20000000; // 512 megabytes // Create the memory-mapped file. using (var mmf = MemoryMappedFile.CreateFromFile(@"c:ExtremelyLargeImage.data", FileMode.Open,"ImgA")) { // Create a random access view, from the 256th megabyte (the offset) // to the 768th megabyte (the offset plus length). using (var accessor = mmf.CreateViewAccessor(offset, length)) { int colorSize = Marshal.SizeOf(typeof(MyColor)); MyColor color; // Make changes to the view. for (long i = 0; i < length; i += colorSize) { accessor.Read(i, out color); color.Brighten(10); accessor.Write(i, ref color); } } } } } public struct MyColor { public short Red; public short Green; public short Blue; public short Alpha; // Make the view brighter. public void Brighten(short value) { Red = (short)Math.Min(short.MaxValue, (int)Red + value); Green = (short)Math.Min(short.MaxValue, (int)Green + value); Blue = (short)Math.Min(short.MaxValue, (int)Blue + value); Alpha = (short)Math.Min(short.MaxValue, (int)Alpha + value); } } // Assumes another process has created the memory-mapped file. using (var mmf = MemoryMappedFile.OpenExisting("ImgA")) { using (var accessor = mmf.CreateViewAccessor(4000000, 2000000)) { int colorSize = Marshal.SizeOf(typeof(MyColor)); MyColor color; // Make changes to the view. for (long i = 0; i < 1500000; i += colorSize) { accessor.Read(i, out color); color.Brighten(20); accessor.Write(i, ref color); } } }
非持久化内存映射文件
CreateNew 和 CreateOrOpen 方法创建未映射到磁盘上现有文件的内存映射文件。