c# 通过内存映射实现文件共享内存的示例代码
作者:zls365 发布时间:2023-03-02 12:15:35
标签:c#,内存映射,共享内存
内存映射文件是利用虚拟内存把文件映射到进程的地址空间中去,在此之后进程操作文件,就像操作进程空间里的地址一样了,比如使用c语言的 memcpy等内存操作的函数。这种方法能够很好的应用在需要频繁处理一个文件或者是一个大文件的场合,这种方式处理IO效率比普通IO效率要高
共享内存是内存映射文件的一种特殊情况,内存映射的是一块内存,而非磁盘上的文件。共享内存的主语是进程(Process),操作系统默认会给每一 个进程分配一个内存空间,每一个进程只允许访问操作系统分配给它的哪一段内存,而不能访问其他进程的。而有时候需要在不同进程之间访问同一段内存,怎么办 呢?操作系统给出了创建访问共享内存的API,需要共享内存的进程可以通过这一组定义好的API来访问多个进程之间共有的内存,各个进程访问这一段内存就 像访问一个硬盘上的文件一样。而.Net 4.0中引入了System.IO. MemoryMappedFiles命名空间,这个命名空间的类对windows 共享内存相关API做了封装,使.Net程序员可以更方便的使用内存映射文件。
在C#中使用共享内存。以下App1的代码让用户输入一行文本到共享内存中;App2不停的刷新控制台,输出最新的共享内存内容;App3实现的功能和App2相同,但读取方法不同。
App1代码:
using System;
using System.Collections.Generic;android从资源文件中读取文件流显示
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代码:
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代码:
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();
}
}
}
}
}
}
}
在读数据时用了2种方法。
因为在之前很少会用到进程之间的通信,所以此方法只是想初步的认识下。此程序写的过于简陋,有很多东西都没有去判断。比如说是怎么创建了一个共享内存怎么取删除它等等。。。
来源:https://mp.weixin.qq.com/s/RIozylOT3tGodyKgCZHpAA


猜你喜欢
- Java定义Long数据类型Long lg=10L;只需要在定义的的整型后面加个L;就和定义float数据类型一样Float ft=5.20
- 概述在实际项目开发中如果需要支持多语言,我们需要整理项目中所有的字符串并翻译成对应的语种放在相应的文件夹下,就像这样最让我们头痛的是我们得一
- static和const是C++程序设计中非常重要的概念,本文实例列举了C++类中的static和const的规则和用法。供大家参考借鉴。具
- 互连网早期的时候,主机间的互连使用的是NCP协议。这种协议本身有很多缺陷,如:不能互连不同的主机,不能互连不同的操作系统,没有纠错功能。为了
- 本文实例为大家分享了Android实现语音播放与录音的具体代码,供大家参考,具体内容如下项目用到的技术点和亮点语音录音 (单个和列表)语音播
- 效果图如下所述:布局<?xml version="1.0" encoding="utf-8"?
- 先给大家这是下效果图:谷歌提供的v4包,ViewPager在布局文件中,先添加<android.support.v4.view.Vie
- 本文为大家分享了Android实现带动画效果的可点击展开TextView 制作代码,效果图: 收起(默认)效果:点击展开后的效果:源码: 布
- 一、概念 1. 为了能让程序操作数据库,对数据库中的表进行操作,每一种数据库都会提供一套连接和操作该数据库的驱动,而且每种数据库
- 前言 安卓系统中,Button是程序和用户进行交互的一个重要控件,今天我们就来简单的对Button进行学习,其中Bu
- 背景:使用Idea编辑器一. SpringBoot项目打war包步骤:在pom.xml文件中的<build>标签,使用<f
- idea如何设置系统环境变量背景最近在接入阿里云的短信服务,在使用阿里云短信服务的SDK过程中想看看SDK中HttpUtil 中public
- 本文实例为大家分享了Android自定义View画天气预报折线图的具体代码,供大家参考,具体内容如下效果图如下:刚开始尝试用第三方画曲线的框
- 主要是重写attemptAuthentication方法导入依赖<dependency><groupId>org.s
- (1)首先实现AutoCompleteTextView功能所需要的适配器数据源共有两种方法,一种结果是手工配置的,另一汇总是通过xml文件制
- 本文实例为大家分享了springboot实现基于aop的切面日志的具体代码,供大家参考,具体内容如下通过aop的切面方式实现日志通切面拦截所
- 首先,说说final。final关键字可以修饰变量,方法,类。final变量:需求:1 需要一个永不改变的编译时常量2 一个运行时被初始化的
- ArrayBlockingQueue介绍ArrayBlockingQueue是数组实现的线程安全的有界的阻塞队列。线程安全是指,ArrayB
- 问题:对于多线程编程,很多时候往往需要向线程中传递多个参数,而C#中的线程只接收1个object类型的参数(如下):Thread t = n
- 本文实例讲述了C#实现的算24点游戏算法。分享给大家供大家参考。具体如下:using System;using System.Collect