- 浏览: 528731 次
文章分类
最新评论
-
chaodilei:
我可以提个意见吗?作为前端工程师,写博客应该注意段落标题的ba ...
我的前端之路 -
zhuchao_ko:
大家一起二。
我的前端之路
C#内存映射文件学习
内存映射文件是由一个文件到进程地址空间的映射。
C#提供了允许应用程序把文件映射到一个进程的函(MemoryMappedFile.CreateOrOpen)。内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,只是内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而非系统的页文件,而且在对该文件进行操作之前必须首先对文件进行映射,就如同将整个文件从磁盘加载到内存。由此可以看出,使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,这意味着在对文件进行处理时将不必再为文件申请并分配缓存,所有的文件缓存操作均由系统直接管理,由于取消了将文件数据加载到内存、数据从内存到文件的回写以及释放内存块等步骤,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。另外,实际工程中的系统往往需要在多个进程之间共享数据,如果数据量小,处理方法是灵活多变的,如果共享数据容量巨大,那么就需要借助于内存映射文件来进行。实际上,内存映射文件正是解决本地多个进程间数据共享的最有效方法。
共享内存是内存映射文件的一种特殊情况,内存映射的是一块内存,而非磁盘上的文件。共享内存的主语是进程(Process),操作系统默认会给每一个进程分配一个内存空间,每一个进程只允许访问操作系统分配给它的哪一段内存,而不能访问其他进程的。而有时候需要在不同进程之间访问同一段内存,怎么办呢?操作系统给出了创建访问共享内存的API,需要共享内存的进程可以通过这一组定义好的API来访问多个进程之间共有的内存,各个进程访问这一段内存就像访问一个硬盘上的文件一样。而.Net 4.0中引入了System.IO.MemoryMappedFiles命名空间,这个命名空间的类对windows 共享内存相关API做了封装,使.Net程序员可以更方便的使用内存映射文件。
内存映射文件实现进程间通讯
内存映射文件是实现进程通讯的又一种方法,我们可以通过共享剪贴板、共享物理文件来实现进程间的数据共享,这里我们还可以通过内存映射文件来实现共享,这样,文件内的数据就可以用内存读/写指令来访问,而不是用ReadFile和WriteFile这样的I/O系统函数,从而提高了文件存取速度。这种方式更加快捷高效,最适用于需要读取文件并且对文件内包含的信息做语法分析的应用程序,如:对输入文件进行语法分析的彩色语法编辑器,编译器等。这种数据共享是让两个或多个进程映射同一文件映射对象的视图,即它们在共享同一物理存储页。这样,当一个进程向内存映射文件的一个视图写入数据时,其他的进程立即在自己的视图中看到变化。
注意:
对文件映射对象要使用同一名字。
是让两个或多个进程映射同一文件映射对象的视图,即它们在共享同一物理存储页。这样,当一个进程向内存映射文件的一个视图写入数据时,其他的进程立即在自己的视图中看到变化。但要注意,对文件映射对象要使用同一名字。
内存映射文件使用实例:
1.在同一进程内同时读写同一内存映射文件
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using System.IO.MemoryMappedFiles; namespace UseMMFInProcess { public partial class frmMain : Form { public frmMain() { InitializeComponent(); CreateMemoryMapFile(); } private const int FILE_SIZE = 512; /// <summary> /// 引用内存映射文件 /// </summary> private MemoryMappedFile memoryFile = null; /// <summary> /// 用于访问内存映射文件的存取对象 /// </summary> private MemoryMappedViewAccessor accessor1, accessor2,accessor; /// <summary> /// 创建内存映射文件 /// </summary> private void CreateMemoryMapFile() { try { memoryFile = MemoryMappedFile.CreateFromFile("MyFile.dat", FileMode.OpenOrCreate, "MyFile", FILE_SIZE); //访问文件前半段 accessor1 = memoryFile.CreateViewAccessor(0, FILE_SIZE / 2); //访问文件后半段 accessor2 = memoryFile.CreateViewAccessor(FILE_SIZE / 2, FILE_SIZE / 2); //访问全部文件 accessor = memoryFile.CreateViewAccessor(); //InitFileContent(); lblInfo.Text = "内存文件创建成功"; ShowFileContents(); } catch (Exception ex) { lblInfo.Text = ex.Message; } } /// <summary> /// 关闭并释放资源 /// </summary> private void DisposeMemoryMapFile() { if (accessor1 != null) accessor1.Dispose(); if (accessor2 != null) accessor2.Dispose(); if (memoryFile != null) memoryFile.Dispose(); } private void frmMain_FormClosing(object sender, FormClosingEventArgs e) { DisposeMemoryMapFile(); } private void btnWrite1_Click(object sender, EventArgs e) { if (textBox1.Text.Length == 0) { lblInfo.Text = "请输入一个字符"; return; } char[] chs = textBox1.Text.ToCharArray(); char ch = chs[0]; for (int i = 0; i < FILE_SIZE / 2; i += 2) accessor1.Write(i, ch); lblInfo.Text = "字符“" + ch + "”已写到文件前半部份"; ShowFileContents(); } private void btnShow_Click(object sender, EventArgs e) { ShowFileContents(); } /// <summary> /// 初始化文件内容为可视的字符“0” /// </summary> private void InitFileContent() { for (int i = 0; i < FILE_SIZE; i += 2) accessor.Write(i,'0'); } /// <summary> /// 显示文件内容 /// </summary> private void ShowFileContents() { StringBuilder sb = new StringBuilder(FILE_SIZE); sb.Append("上半段内容:\n"); int j = 0; for (int i = 0; i < FILE_SIZE / 2; i += 2) { sb.Append("\t"); char ch = accessor.ReadChar(i); sb.Append(j); sb.Append(":"); sb.Append(ch); j++; } sb.Append("\n下半段内容:\n"); for (int i = FILE_SIZE / 2; i < FILE_SIZE; i += 2) { sb.Append("\t"); char ch = accessor.ReadChar(i); sb.Append(j); sb.Append(":"); sb.Append(ch); j++; } richTextBox1.Text = sb.ToString(); } private void btnWrite2_Click(object sender, EventArgs e) { if (textBox2.Text.Length == 0) { lblInfo.Text = "请输入一个字符"; return; } char[] chs = textBox2.Text.ToCharArray(); char ch = chs[0]; for (int i = 0; i < FILE_SIZE / 2; i += 2) accessor2.Write(i, ch); lblInfo.Text = "字符“" + ch + "”已写到文件后半部份"; ShowFileContents(); } } }
2.使用内存映射文件在进程间传送值类型数据
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace UseMMFBetweenProcess { /// <summary> /// 要共享的数据结构,注意,其成员不能是引用类型 /// </summary> public struct MyStructure { public int IntValue { get; set; } public float FloatValue { get; set; } } } using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO.MemoryMappedFiles; using System.IO; namespace UseMMFBetweenProcess { public partial class frmMain : Form { public frmMain() { InitializeComponent(); InitMemoryMappedFile(); } /// <summary> /// 内存映射文件的容量 /// </summary> private const int FileSize = 1024 * 1024; private MemoryMappedFile file = null; private MemoryMappedViewAccessor accessor = null; /// <summary> /// 初始化内存映射文件 /// </summary> private void InitMemoryMappedFile() { file = MemoryMappedFile.CreateOrOpen("UseMMFBetweenProcess", FileSize); accessor = file.CreateViewAccessor(); lblInfo.Text = "内存文件创建或连接成功"; } /// <summary> /// 要共享的数据对象 /// </summary> private MyStructure data; /// <summary> /// 显示数据到窗体上 /// </summary> private void ShowData() { textBox1.Text = data.IntValue.ToString(); textBox2.Text = data.FloatValue.ToString(); } /// <summary> /// 根据用户输入更新数据 /// </summary> private void UpdateData() { data.IntValue = int.Parse(textBox1.Text); data.FloatValue = float.Parse(textBox2.Text); } private void btnSave_Click(object sender, EventArgs e) { try { UpdateData(); accessor.Write<MyStructure>(0, ref data); lblInfo.Text = "数据已经保存到内存文件中"; } catch (Exception ex) { lblInfo.Text = ex.Message; } } private void btnLoad_Click(object sender, EventArgs e) { accessor.Read<MyStructure>(0, out data); ShowData(); lblInfo.Text = "成功从内存文件中提取了数据"; } private void frmMain_FormClosing(object sender, FormClosingEventArgs e) { if (accessor != null) accessor.Dispose(); if (file != null) file.Dispose(); } } }
3.利用序列化技术通过内存映射文件实现进程通讯
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using System.IO.MemoryMappedFiles; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; namespace UseMMFBetweenProcess2 { public partial class frmMain : Form { public frmMain() { InitializeComponent(); InitMemoryMappedFile(); } /// <summary> /// 图片 /// </summary> private Image bmp { get { return pictureBox1.Image; } set { pictureBox1.Image = value; } } /// <summary> /// 图片说明 /// </summary> private string info { get { return txtImageInfo.Text; } set { txtImageInfo.Text = value; } } private MemoryMappedFile memoryFile = null; private MemoryMappedViewStream stream = null; /// <summary> /// 最大容量:10M /// </summary> private const int FileSize = 1024 * 1024 * 10; /// <summary> /// 创建内存映射文件,获取其读写流 /// </summary> private void InitMemoryMappedFile() { try { memoryFile = MemoryMappedFile.CreateOrOpen("UseMMFBetweenProcess2", FileSize); stream = memoryFile.CreateViewStream(); } catch (Exception ex ) { MessageBox.Show(ex.Message); Close(); } } /// <summary> /// 释放相关资源 /// </summary> private void DisposeMemoryMappedFile() { if (stream != null) stream.Close(); if (memoryFile != null) memoryFile.Dispose(); } private void btnLoadPic_Click(object sender, EventArgs e) { ChooseImageFile(); } //选择图片 private void ChooseImageFile() { if (openFileDialog1.ShowDialog() == DialogResult.OK) { bmp = new Bitmap(openFileDialog1.FileName); } } //根据用户设定的信息创建对象 private MyPic CreateMyPicObj() { MyPic obj = new MyPic(); obj.pic = bmp; obj.picInfo = info; return obj; } /// <summary> /// 将MyPic对象保存到内存映射文件中 /// </summary> private void SaveToMMF() { try { MyPic obj = CreateMyPicObj(); IFormatter formatter = new BinaryFormatter(); stream.Seek(0, SeekOrigin.Begin); formatter.Serialize(stream, obj); MessageBox.Show("对象已保存到内存映射文件中"); } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void LoadFromMMF() { try { // CreateMyPicObj(); IFormatter formatter = new BinaryFormatter(); stream.Seek(0, SeekOrigin.Begin); MyPic obj = formatter.Deserialize(stream) as MyPic; if (obj != null) { bmp = obj.pic; info = obj.picInfo; } } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void btnExit_Click(object sender, EventArgs e) { Close(); } private void frmMain_FormClosing(object sender, FormClosingEventArgs e) { DisposeMemoryMappedFile(); } private void btnSaveToMMF_Click(object sender, EventArgs e) { SaveToMMF(); } private void btnLoadFromMMF_Click(object sender, EventArgs e) { LoadFromMMF(); } } }
相关推荐
C# 基于类的内存文件映射,源代码,使用了类定义,写的时候直接创建类,类会自动对应到共享文件,源代码依供参数
Visual C++ .NET环境下采用内存映射文件设计超大文件数据编辑器
通过.net 4.0中的新类库使用内存映射文件
VC++中使用内存映射编程方面的资料,希望对大家有用; 彻底共享,决不要分!
通过网上资料自己开发的只是个初稿还有一定的问题希望大家可以完善哈哈
C#通过WinIO读取BIOS的版本号 可用于工控行业的测试 程序包里有自己封装好的函数库,里面有对WinIO的操作,使用起来比较简单 这支程序可直接使用,用于工厂测试产品烧录的BIOS版本号 提供了完整的源码,使用时加个...
重点展示如何使用.NET4.0中新增的MemoryMappedFile类实现进程间通讯,资源包中包含一个PDF文档,以及VS2010格式的三个示例文件。 与作者交流请访问 http://blog.csdn.net/bitfan/archive/2009/08/12/4438458.aspx 更...
该资源用c#实现了内存映射文件共享内存,初学者应该比较好懂。Shared Memory1和Shared Memory2是一组共享内存的读写,Shared Memory3和WriteRead也是一组共享内存的读写
当处理大型数据或需要在多个进程(或多个程序)之间共享数据时,MemoryMappedFiles(内存映射文件)是一种非常有用的技术。它允许将文件映射到进程的虚拟内存中,从而可以直接在内存中读取和写入文件的内容,而无需...
共享内存C#共享内存类,用于在进程之间共享数据(数组,缓冲区,循环缓冲区和RPC)关于SharedMemory类库提供了一组C#类,这些C#类利用内存映射文件进行快速的低级进程间通信(IPC)。 最初仅用于在进程之间共享...
10.内存映射文件(Memory-Mapped Files) 11.命名事件(Named Events) 12.剪贴板(Clipboard) 13.COM(Component Object Model)和DCOM(Distributed COM) 14.WCF(Windows Communication Foundation) 这些只是...
持久队列 将数据持久化到内存映射文件的队列。 工作正在进行中...
MappedMemoryFiles:映射内存文件 DriveViewer:读取驱动器信息,展示了DriveInfo类的用法 ReadingACLs:查看指定文件的ACL(访问控制列表) ReadingACLsFromDirectory:读取目录(而不是文件)的ACL信息 ...
文件映射是两进程共享内存的重要方法。用文件映射实现了USER和NETWORK两进程之间的共享内存,并对其函数和函数的参数进行了解释。
这个简单的解决方案包含... 进程通过内存映射文件进行交互。 非托管 C++ 进程在启动时在 C# 进程中启动。 所有交互行为都是通过具有自动重置的同步事件实现的。 解决方案不依赖于除 .net framework 4.5 之外的任何组件
c#学习笔记(1) 51099在线学习网发布 文章来源:网络收集 发布时间:2006-05-25 字体: [大 中 小] 51099在线学习网 http://www.51099.com 1, 结构(struct) 与 类(class) [attributes] [modifiers] struct ...
最大支持总存储空间 1.5GB(内存映射文件限制) 支持文件随机访问和读取,也支持顺序访问和读取 支持 Seek,可以快速创建很大的空文件 懒惰分配数据区块,即只有在需要对数据区块写入时,才会查找并分配区块 底层...
第一部分 C#语言概述.4 第一章 第一章第一章 第一章 .NET 编 编 编程语言 程语言编程语言 程语言 C#.4 1.1 Microsoft.NET——一场新的革命.4 1.2 .NET 与 C#.6 1.3 C#语言的特点.8 1.4 小 结 .11...
c#读写大文件(内存映射方式)