首页 技术 正文
技术 2022年11月6日
0 收藏 866 点赞 809 浏览 4186 个字

内存映射文件是利用虚拟内存把文件映射到进程的地址空间中去,在此之后进程操作文件,就 像操作进程空间里的地址一样了,比如使用c语言的memcpy等内存操作的函数。这种方法能够很好的应用在需要频繁处理一个文件或者是一个大文件的场合, 这种方式处理IO效率比普通IO效率要高

共享内存是内存映射文件的一种特殊情况,内存映射的是一块内存,而非磁盘上的文件。共享内存的主语是进程(Process),操作系统默认会给每一 个进程分配一个内存空间,每一个进程只允许访问操作系统分配给它的哪一段内存,而不能访问其他进程的。而有时候需要在不同进程之间访问同一段内存,怎么办 呢?操作系统给出了创建访问共享内存的API,需要共享内存的进程可以通过这一组定义好的API来访问多个进程之间共有的内存,各个进程访问这一段内存就 像访问一个硬盘上的文件一样。而.Net 4.0中引入了System.IO. MemoryMappedFiles命名空间,这个命名空间的类对windows 共享内存相关API做了封装,使.Net程序员可以更方便的使用内存映射文件。

在C#中使用共享内存。以下App1的代码让用户输入一行文本到共享内存中;App2不停的刷新控制台,输出最新的共享内存内容;App3实现的功能和App2相同,但读取方法不同。

App1代码:

123456789101112131415161718192021222324252627282930313233343536373839404142 using System;using System.Collections.Generic;using System.Linq;using System.Text; using System.IO; //引用内存映射文件命名空间using System.IO.MemoryMappedFiles; namespace App1{    class Program    {        static void Main(string[] args)        {            long capacity = 1<<10<<10;             //创建或者打开共享内存            using (var mmf = MemoryMappedFile.CreateOrOpen("testMmf", capacity, MemoryMappedFileAccess.ReadWrite))            {                //通过MemoryMappedFile的CreateViewAccssor方法获得共享内存的访问器                var viewAccessor = mmf.CreateViewAccessor(0, capacity);                //循环写入,使在这个进程中可以向共享内存中写入不同的字符串值                while (true)                {                    Console.WriteLine("请输入一行要写入共享内存的文字:");                     string input = Console.ReadLine();                     //向共享内存开始位置写入字符串的长度                    viewAccessor.Write(0, input.Length);                     //向共享内存4位置写入字符                    viewAccessor.WriteArray<char>(4, input.ToArray(), 0, input.Length);                }             }                     }    }}

App2代码:

1234567891011121314151617181920212223242526272829303132333435363738 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading; //引用使用内存映射文件需要的命名空间using System.IO.MemoryMappedFiles; namespace App2{    class Program    {        static void Main(string[] args)        {              long capacity = 1<<10<<10;               using (var mmf = MemoryMappedFile.OpenExisting("testMmf"))              {                  MemoryMappedViewAccessor viewAccessor = mmf.CreateViewAccessor(0, capacity);                   //循环刷新共享内存字符串的值                  while (true)                  {                      //读取字符长度                      int strLength = viewAccessor.ReadInt32(0);                                            char[] charsInMMf = new char[strLength];                      //读取字符                      viewAccessor.ReadArray<char>(4, charsInMMf, 0, strLength);                      Console.Clear();                      Console.Write(charsInMMf);                      Console.Write("\r");                      Thread.Sleep(200);                  }              }        }    }}

App3代码:

1234567891011121314151617181920212223242526272829303132333435363738394041424344 using System;using System.Collections.Generic;using System.Linq;using System.Text; using System.IO.MemoryMappedFiles;using System.IO; namespace App3{    class Program    {        static void Main(string[] args)        {            long capacity = 1 << 10 << 10;            //打开共享内存            using (var mmf = MemoryMappedFile.OpenExisting("testMmf"))            {                //使用CreateViewStream方法返回stream实例                using (var mmViewStream = mmf.CreateViewStream(0, capacity))                {                    //这里要制定Unicode编码否则会出问题                    using (BinaryReader rdr = new BinaryReader(mmViewStream,Encoding.Unicode))                    {                        while (true)                        {                            mmViewStream.Seek(0, SeekOrigin.Begin);                             int length = rdr.ReadInt32();                             char[] chars = rdr.ReadChars(length);                             Console.Write(chars);                            Console.Write("\r");                             System.Threading.Thread.Sleep(200);                            Console.Clear();                        }                    }                }            }        }    }}

单这么写也许大家不理解内存映射文件的使用,下一篇想写一篇介绍内存映射文件应用实例的文章。

相关随笔: .Net那点事儿系列:System.IO之windows文件操作
.Net那点事儿系列:System.IO之Stream

System.IO之内存映射文件共享内存

System.IO之使用管道在进程间通信 (System.IO.Pipes使用)

System.IO系列:局域网内多线程使用命名管道在进程之间通信实例

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,488
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,903
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,736
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,487
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,127
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,289