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
0
投稿
猜你喜欢
- 上一篇文章讲解了Spring Cloud 整合 nacos 实现服务注册与发现,nacos除了有服务注册与发现的功能,还有提供动态配置服务的
- 线程中run()和start()的区别:对于Thread对象来说,当你调用的是start(),线程会被放到等待队列,等待CPU调度,不一定马
- 分析Github 3000个开源项目,粗略统计如下。括号内的数字是使用频率 0-3000. 下面的列表显示不全,完整的请看完整列表。1.ja
- 一、问题描述如果在 SpringBoot 项目中的 application.properties 配置了某个属性(假如属性名为 test.k
- 前言上一篇通过clusterservice对cluster做了一个简单的概述, 应该能够给大家一个初步认识。本篇将对cluster的代码组成
- 最近有时间,写一些很简单、很基础的东西,主要在操作层面。主要考虑如下: 1、经常搭建开发环境,所以有必要记录一下,自己也可以备查; 2、给新
- Maven导入thymeleaf依赖飘红1、运行环境操作系统:win10jdk版本:1.8idea版本:2020.1maven版本:3.3.
- 在日常的开发中、我们都知道,Java的内存清理是通过垃圾回收器进行的,那么其是如何将没用的对象被被清理掉的呢?Java 语言的内存自动回收称
- 本文实例讲述了Spring计划任务用法。分享给大家供大家参考,具体如下:一 点睛从Spring3.1开始,计划任务在Spring中的实现变得
- 本文实例为大家分享了C#实现简易点餐功能的具体代码,供大家参考,具体内容如下图示效果实现过程1.设计界面2.设计控件及其属性3.实现点击事件
- 目录背景解决方案1、设置热点数据永远不过期。2、加互斥锁,互斥锁参考代码如下:总结说明1、缓存中有数据,直接走下述代码就返回结果了2、缓存中
- itextpdf解决PDF合并的问题本文章是我在项目开发过程中解决了一个关于PDF显示的需求而记录的。需求是这样的,需要将两个PDF进行合并
- 文件上传在web应用中非常普遍,要在jsp环境中实现文件上传功能是非常容易的,因为网上有许多用java开发的文件上传组件,本文以common
- 一、项目简述功能包括(管理员和用户角色): 酒店预订,酒店管理,员工管理,入住原理,订单管理, 楼层管理,退房管理,营业额报表等等。二、项目
- springboot 异常与重定向在spring中,有两个重定向类型:301,永久性跳转302,暂时性跳转默认调用302。1.下面先通过一个
- 在Android上,不止一个途径来侦听用户和应用程序之间交互的事件。对于用户界面里的事件,侦听方法就是从与用户交互的特定视图对象截获这些事件
- 在项目开发中,我们经常会遇到表中的字段名和表对应实体类的属性名称不一定都是完全相同的情况,下面小编给大家演示一下这种情况下的如何解决字段名与
- 在同一个类中: 对于静态方法,其他的静态或非静态方法都可以直接调用它。而对于非静态方法,其他的非静态方法是可以直接调用它的。但是其他静态方法
- jol(java object layout)需要的依赖<dependency> <
- ref和out都是C#中的关键字,所实现的功能也差不多,都是指定一个参数按照引用传递。对于编译后的程序而言,它们之间没有任何区别,也就是说它