内存映射文件允许访问文件,或在不同的进程中共享内容。这个技术有几个场景和特点:
- 使用文件地图,快速随机访问大文件
- 在不同的进程或任务之间共享文件
- 在不同的进程或任务之间共享内容
- 使用访问器直接从内存位置进行读写
- 使用流进行读写
内存映射文件API允许使用物理文件或共享的内存,其中把系统的页面文件用作后备存储器。共享的内存可以大于可用的物理内存,所以需要一个后备存储器。可以为特定的文件或共享的内存创建一个内存映射文件。使用这两个选项,可以给内存映射指定名称。使用名称,允许不同的进程访问同一个共享的内存。
创建了内存映射之后,就可以创建一个视图。视图用于映射完整内存映射文件的一部分,以访问它,进行读写。
MemoryMappedFilesSample利用下面的名称空间:
System
System.IO
System.IO.MemoryMappedFiles
System.Theading
System.Threading.Tasks
示例应用程序演示了如何通过内存映射文件,使用这两种视图访问器和流完成多个任务。一个任务是创建内存映射文件和写入数据;另一个任务是读取数据。
准备好映射,写入数据时,需要一些基础设施来创建任务,发出信号。映射的名称和ManualResetEventSlim对象定义为Program类的一个成员:
private static ManualResetEventSlim _mapCreated = new ManualResetEventSlim(initialState: false);
private static ManualResetEventSlim _dataWrittenEvent = new ManualResetEventSlim(initialState: false);
private const string MAPNAME = "SampleMap";
在Main()方法中使用Task.Run()方法开始执行任务:
static async Task Run()
{
var writer = Task.Run(async() => await WriterAsync());
var reader = Task.Run(() => Reader());
Console.WriteLine("tasks started");
await Task.WhenAll(writer, reader);
}
现在使用访问器创建读取器和写入器。
1. 使用访问器创建内存映射文件
为了创建一个基于内存的内存映射文件,写入器调用了MemoryMappedFile.CreateOrOpen方法。这个方法打开第一个参数指定名称的对象,如果它不存在,就创建了一个新对象。要打开现有的MemoryMappedFile对象,可以使用OpenExisting方法。为了访问物理文件,可以使用CreateFromFile方法。
示例代码中使用的其他参数是内存映射文件的大小和所需的访问。创建内存映射文件后,给事件_mapCreated发出信号,给其他任务提供信息,说明已经创建了内存映射文件,可以打开它了。调用方法CreateViewAccessor,返回一个MemoryMappedViewAccessor,以访问共享的内存。使用视图访问器,可以定义这一任务使用的偏移量和大小。当然,可以使用的最大大小是内存映射文件的大小。这个视图用于写入,因此文件访问设置为MemoryMappedFileAcce