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

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

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

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

App1代码:

01using System;
02using System.Collections.Generic;
03using System.Linq;
04using System.Text;
05  
06using System.IO;
07  
08//引用内存映射文件命名空间
09using System.IO.MemoryMappedFiles;
10  
11namespace App1
12{
13    class Program
14    {
15        static void Main(string[] args)
16        {
17            long capacity = 1<<10<<10;
18  
19            //创建或者打开共享内存
20            using (var mmf = MemoryMappedFile.CreateOrOpen("testMmf", capacity, MemoryMappedFileAccess.ReadWrite))
21            {
22                //通过MemoryMappedFile的CreateViewAccssor方法获得共享内存的访问器
23                var viewAccessor = mmf.CreateViewAccessor(0, capacity);
24                //循环写入,使在这个进程中可以向共享内存中写入不同的字符串值
25                while (true)
26                {
27                    Console.WriteLine("请输入一行要写入共享内存的文字:");
28  
29                    string input = Console.ReadLine();
30  
31                    //向共享内存开始位置写入字符串的长度
32                    viewAccessor.Write(0, input.Length);
33  
34                    //向共享内存4位置写入字符
35                    viewAccessor.WriteArray<char>(4, input.ToArray(), 0, input.Length);
36                }
37  
38            }
39              
40        }
41    }
42}

App2代码:

01using System;
02using System.Collections.Generic;
03using System.Linq;
04using System.Text;
05using System.Threading;
06  
07//引用使用内存映射文件需要的命名空间
08using System.IO.MemoryMappedFiles;
09  
10namespace App2
11{
12    class Program
13    {
14        static void Main(string[] args)
15        {
16              long capacity = 1<<10<<10;
17  
18              using (var mmf = MemoryMappedFile.OpenExisting("testMmf"))
19              {
20                  MemoryMappedViewAccessor viewAccessor = mmf.CreateViewAccessor(0, capacity);
21  
22                  //循环刷新共享内存字符串的值
23                  while (true)
24                  {
25                      //读取字符长度
26                      int strLength = viewAccessor.ReadInt32(0);                      
27                      char[] charsInMMf = new char[strLength];
28                      //读取字符
29                      viewAccessor.ReadArray<char>(4, charsInMMf, 0, strLength);
30                      Console.Clear();
31                      Console.Write(charsInMMf);
32                      Console.Write("\r");
33                      Thread.Sleep(200);
34                  }
35              }
36        }
37    }
38}

App3代码:

01using System;
02using System.Collections.Generic;
03using System.Linq;
04using System.Text;
05  
06using System.IO.MemoryMappedFiles;
07using System.IO;
08  
09namespace App3
10{
11    class Program
12    {
13        static void Main(string[] args)
14        {
15            long capacity = 1 << 10 << 10;
16            //打开共享内存
17            using (var mmf = MemoryMappedFile.OpenExisting("testMmf"))
18            {
19                //使用CreateViewStream方法返回stream实例
20                using (var mmViewStream = mmf.CreateViewStream(0, capacity))
21                {
22                    //这里要制定Unicode编码否则会出问题
23                    using (BinaryReader rdr = new BinaryReader(mmViewStream,Encoding.Unicode))
24                    {
25                        while (true)
26                        {
27                            mmViewStream.Seek(0, SeekOrigin.Begin);
28  
29                            int length = rdr.ReadInt32();
30  
31                            char[] chars = rdr.ReadChars(length);
32  
33                            Console.Write(chars);
34                            Console.Write("\r");
35  
36                            System.Threading.Thread.Sleep(200);
37                            Console.Clear();
38                        }
39                    }
40                }
41            }
42        }
43    }
44}

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

转载于:https://www.cnblogs.com/qiuweiguo/archive/2011/08/03/2126296.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值