MemoryMappedFile 内存映射文件 msdn
http://msdn.microsoft.com/zh-cn/library/dd997372%28v=vs.110%29.aspx
内存映射文件
内存映射文件包含虚拟内存中文件的内容。 利用文件与内存空间之间的映射,应用程序(包括多个进程)可以通过直接在内存中进行读写来修改文件。 从 .NET Framework 4开始,可以使用托管代码按照本机Windows函数访问内存映射文件的方式来访问内存映射文件,如 MSDN Library 中的Managing Memory-Mapped Files in Win32 (管理 Win32 中的内存映射文件)中所述。
有两种类型的内存映射文件:
持久内存映射文件
持久文件是与磁盘上的源文件关联的内存映射文件。 在最后一个进程使用完此文件后,数据将保存到磁盘上的源文件中。 这些内存映射文件适合用来处理非常大的源文件。
非持久内存映射文件
非持久文件是未与磁盘上的源文件关联的内存映射文件。 当最后一个进程使用完此文件后,数据将丢失,并且垃圾回收功能将回收此文件。 这些文件适用于为进程间通信 (IPC) 创建共享内存。
内存映射文件可以在多个进程之间进行共享。 进程可以通过使用由创建同一内存映射文件的进程所指派的公用名来映射到此文件。
若要使用一个内存映射文件,则必须创建该内存映射文件的完整视图或部分视图。 还可以创建内存映射文件的同一部分的多个视图,进而创建并发内存。 为了使两个视图能够并发,必须基于同一内存映射文件创建这两个视图。
如果文件大于应用程序用于内存映射的逻辑内存空间(在 32 位计算机上为 2 GB),则还需要使用多个视图。
有两种类型的视图:流访问视图和随机访问视图。 使用流访问视图可对文件进行顺序访问;对于非持久文件和 IPC,这是建议的方法。 在使用持久文件时,随机访问视图是首选方法。
由于内存映射文件是通过操作系统的内存管理器访问的,因此会自动将此文件分隔为多个页,并根据需要对其进行访问。 您不需要自行处理内存管理。
下图演示多个进程如何同时具有对同一内存映射文件的多个重叠视图。
下表提供有关使用内存映射文件对象及其成员的指南。
|
任务 |
使用的方法或属性 |
|---|---|
|
从磁盘上的文件中获取表示持久内存映射文件的 MemoryMappedFile 对象。 |
|
|
获取表示非持久内存映射文件(与磁盘上的文件不关联)的 MemoryMappedFile 对象。 |
MemoryMappedFile.CreateNew - 或 - |
|
获取现有内存映射文件(持久文件或非持久文件)的 MemoryMappedFile 对象。 |
|
|
获取针对内存映射文件的顺序访问视图的 UnmanagedMemoryStream 对象。 |
|
|
获取针对内存映射文件的随机访问视图的 UnmanagedMemoryAccessor 对象。 |
|
|
获取要用于非托管代码的 SafeMemoryMappedViewHandle 对象。 |
MemoryMappedFile.SafeMemoryMappedFileHandle - 或 - MemoryMappedViewAccessor.SafeMemoryMappedViewHandle - 或 - |
|
将内存分配推迟到创建视图后进行(仅限于非持久文件)。 (若要确定当前系统页大小,请使用 Environment.SystemPageSize 属性。) |
带 MemoryMappedFileOptions.DelayAllocatePages 值的 CreateNew 方法。 - 或 - 将 MemoryMappedFileOptions 枚举作为参数的 CreateOrOpen 方法。 |
安全性
在创建内存映射文件时,可以通过使用以下方法(这些方法采用 MemoryMappedFileAccess 枚举作为参数)来应用访问权限:
通过使用将 MemoryMappedFileRights 用作参数的 OpenExisting 方法,可以指定用于打开现有内存映射文件的访问权限。
此外,可以包含一个 MemoryMappedFileSecurity 对象,该对象包括预定义的访问规则。
若要将新的或已更改的访问规则应用于内存映射文件,请使用 SetAccessControl 方法。
若要从现有文件中检索访问规则或审核规则,请使用 GetAccessControl 方法。
持久内存映射文件
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);
}
}
下面的示例为另一个进程打开同一内存映射文件。
using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices; class Program
{
static void Main(string[] args)
{
// 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);
}
}
}
}
} public struct MyColor
{
public short Red;
public short Green;
public short Blue;
public short Alpha; // Make the view brigher.
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);
}
}
非持久内存映射文件
CreateNew 和 CreateOrOpen 方法创建一个未映射到磁盘上的现有文件的内存映射文件。
下面的示例由三个单独的进程(控制台应用程序)组成,这些进程将布尔值写入到内存映射文件中。 将发生下面一系列操作:
Process A 创建内存映射文件并将一个值写入到其中。
Process B 打开内存映射文件并将一个值写入到其中。
Process C 打开内存映射文件并将一个值写入到其中。
Process A 读取并显示内存映射文件中的值。
Process A 使用完内存映射文件后,垃圾回收功能将会立即回收该文件。
若要运行此示例,请执行以下步骤:
编译应用程序并打开三个命令提示符窗口。
在第一个命令提示符窗口中,运行 Process A。
在第二个命令提示符窗口中,运行 Process B。
返回到 Process A 并按 Enter。
在第三个命令提示符窗口中,运行 Process C。
返回到 Process A 并按 Enter。
Process A 的输出如下所示:
Start Process B and press ENTER to continue.
Start Process C and press ENTER to continue.
Process A says: True
Process B says: False
Process C says: True
进程 A
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Threading; class Program
{
// Process A:
static void Main(string[] args)
{
using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("testmap", 10000))
{
bool mutexCreated;
Mutex mutex = new Mutex(true, "testmapmutex", out mutexCreated);
using (MemoryMappedViewStream stream = mmf.CreateViewStream())
{
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(1);
}
mutex.ReleaseMutex(); Console.WriteLine("Start Process B and press ENTER to continue.");
Console.ReadLine(); Console.WriteLine("Start Process C and press ENTER to continue.");
Console.ReadLine(); mutex.WaitOne();
using (MemoryMappedViewStream stream = mmf.CreateViewStream())
{
BinaryReader reader = new BinaryReader(stream);
Console.WriteLine("Process A says: {0}", reader.ReadBoolean());
Console.WriteLine("Process B says: {0}", reader.ReadBoolean());
Console.WriteLine("Process C says: {0}", reader.ReadBoolean());
}
mutex.ReleaseMutex();
}
}
}
进程 B
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Threading; class Program
{
// Process B:
static void Main(string[] args)
{
try
{
using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("testmap"))
{ Mutex mutex = Mutex.OpenExisting("testmapmutex");
mutex.WaitOne(); using (MemoryMappedViewStream stream = mmf.CreateViewStream(1, 0))
{
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(0);
}
mutex.ReleaseMutex();
}
}
catch (FileNotFoundException)
{
Console.WriteLine("Memory-mapped file does not exist. Run Process A first.");
}
}
}
进程 C
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Threading; class Program
{
// Process C:
static void Main(string[] args)
{
try
{
using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("testmap"))
{ Mutex mutex = Mutex.OpenExisting("testmapmutex");
mutex.WaitOne(); using (MemoryMappedViewStream stream = mmf.CreateViewStream(2, 0))
{
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(1);
}
mutex.ReleaseMutex();
}
}
catch (FileNotFoundException)
{
Console.WriteLine("Memory-mapped file does not exist. Run Process A first, then B.");
}
}
}
MemoryMappedFile 内存映射文件 msdn的更多相关文章
- 内存映射文件MemoryMappedFile使用
参考资料: http://blog.csdn.net/bitfan/article/details/4438458 所谓内存映射文件,其实就是在内存中开辟出一块存放数据的专用区域,这区域往往与硬盘上特 ...
- NET 4 中 内存映射文件
原文链接 : http://blogs.msdn.com/salvapatuel/archive/2009/06/08/working-with-memory-mapped-files-in-net- ...
- C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转
原文:C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing ...
- Java利用内存映射文件实现按行读取文件
我们知道内存映射文件读取是各种读取方式中速度最快的,但是内存映射文件读取的API里没有提供按行读取的方法,需要自己实现.下面就是我利用内存映射文件实现按行读取文件的方法,如有错误之处请指出,或者有更好 ...
- C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped
节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing). 内存映射文件对于托管世界的开发人员来说似乎很陌生,但它确实已经是很远古的技术了,而且在操作 ...
- .NET 4.0中使用内存映射文件实现进程通讯
操作系统很早就开始使用内存映射文件(Memory Mapped File)来作为进程间的共享存储区,这是一种非常高效的进程通讯手段.Win32 API中也包含有创建内存映射文件的函数,然而,这些函数都 ...
- C#内存映射文件消息队列实战演练(MMF—MQ)
一.课程介绍 本次分享课程属于<C#高级编程实战技能开发宝典课程系列>中的一部分,阿笨后续会计划将实际项目中的一些比较实用的关于C#高级编程的技巧分享出来给大家进行学习,不断的收集.整理和 ...
- Windows进程间通信--共享内存映射文件(FileMapping)--VS2012下发送和接收
之前以为两个互不相关的程序a.exe b.exe通信就只能通过网络,人家说可以通过发消息,我还深以为不然,对此,我表示万分惭愧. 之前课本上说的进程间通信,有共享内存.管道等之类的,但没有自己操刀写过 ...
- C#内存映射文件学习[转]
原文链接 内存映射文件是由一个文件到进程地址空间的映射. C#提供了允许应用程序把文件映射到一个进程的函(MemoryMappedFile.CreateOrOpen).内存映射文件与虚拟内存有些类似, ...
随机推荐
- drupal CMS
http://drupalchina.cn/ https://www.drupal.org
- [搜片神器]BT种子下载超时很多的问题分析
继续接着第一篇写:使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)[搜片神器] 谢谢园子朋友的支持,已经找到个VPS进行测试,国外的服务器: h31bt.org 大家可以给提点意 ...
- TCP/IP协议原理学习笔记
昨天学习了杨宁老师的TCP/IP协议原理第一讲和第二讲,主要介绍了OSI模型,整理如下: OSI是open system innerconnection的简称,即开放式系统互联参考模型,它把网络协议从 ...
- uva 10791
还算比较水的一个数学题 求因子的最小和 总是用小的数去除 注意特判 是用int不行哦........ #include <cstdio> #include <cmath> ...
- 关于Java中try-catch-finally-return语句的思考
我们知道return语句用在某一个方法中,一是用于返回函数的执行结果,二是用于返回值为void类型的函数中,仅仅是一个return语句(return ;),此时用于结束方法的执行,也即此return后 ...
- Otto开发初探——微服务依赖管理新利器
[编者按]时下,Vagrant 被 DevOps 软件开发商广泛作为开发阶段的本地软件开发环境,而在本文,CERT Division高级研究员介绍的 Otto 则是 Vagrant 开发团队 Hash ...
- python List&Set&Dict交集、并集、差集
1.python List交集.并集.差集 1). 获取两个list 的交集#方法一: a=[2,3,4,5] b=[2,5,8] tmp = [val for val in a if val in ...
- VS2005(vs2008,vs2010)使用map文件查找程序崩溃原因
VS 2005使用map文件查找程序崩溃原因 一般程序崩溃可以通过debug,找到程序在那一行代码崩溃了,最近编一个多线程的程序,都不知道在那发生错误,多线程并发,又不好单行调试,终于找到一个比较好的 ...
- 关于delete和delete[]
[精彩] 求问delete和delete[] 的区别??http://www.chinaunix.net/jh/23/311058.html C++告诉我们在回收用 new 分配的单个对象的内存空间的 ...
- hdu 4291 A Short problem
数学题,找循环节!! 首先g(g(g(n)))=g(x) mod 1e9+7 则可知x有循环节1e9+7; 之后x=g(g(n)),则可算出g(n)的循环节,在算出n的循环节就可以了!! 代码如下: ...