首页 新闻 会员 周边

(C#)有偿求共享内存(MemoryMappedFile)传递byte[]数组的例子

0
悬赏园豆:10 [已解决问题] 解决于 2022-08-29 11:20

也就是进程A将byte[] value=new byte[1,2,3]传递给进程B

特别是内存容量(capacity )不会设置。

=======================

没多少积分了,全给你,且加微信发红包。

PER10的主页 PER10 | 初学一级 | 园豆:8
提问于:2022-08-28 21:30
< >
分享
最佳答案
0

capacity是你最多需要多少就设置多少,这里玩假设我每次一定发送4个字节,如果不定长当然你肯定需要加一个标志来表示结束,由于我是 Linux ,所以为了保持跨平台兼容性所以这么写:

发送端

using System;
using System.IO.MemoryMappedFiles;

namespace test
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            using (MemoryMappedFile m = MemoryMappedFile.CreateFromFile("/tmp/test.tmp",System.IO.FileMode.Create,"test",4))
            {
                byte[] buffer = { 1, 2, 3,4 };
                using(var access = m.CreateViewAccessor(0,4))
                {
                    access.WriteArray(0, buffer, 0, 4);
                }
                Console.WriteLine("写入完毕,按任意键关闭……");
                Console.ReadKey();
            }

        }
    }
}

接受端

using System;
using System.IO.MemoryMappedFiles;
using System.IO;

namespace test2
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            try
            {
                using (MemoryMappedFile m = MemoryMappedFile.CreateFromFile("/tmp/test.tmp", System.IO.FileMode.Open, "test", 4))
                {
                    byte[] buffer = new byte[4];
                    using (var access = m.CreateViewAccessor(0,4))
                    {
                        access.ReadArray(0, buffer, 0, 4);
                    }
                    foreach (var item in buffer)
                    {
                        Console.Write(item);
                    }
                    Console.WriteLine("写入完毕,按任意键关闭……");
                    Console.ReadKey();
                }

            }
            catch (FileNotFoundException)
            {
                Console.WriteLine("共享文件不存在,按任意键关闭……");
                Console.ReadKey();
            }


        }
    }
}

如果仅 win 的话,你可以使用CreateNewOpenExisting函数可以偷偷懒,但是在 Linux 上的 Mono 就千万别用。【至于红包,随你意吧,我不强求,如果想的话直接博客打赏即可】

收获园豆:10
寂静的羽夏 | 小虾三级 |园豆:1781 | 2022-08-28 23:03

感谢热心回答。里面的m.CreateViewAccessor(0,4)的4,单位就是几个byte吧?

PER10 | 园豆:8 (初学一级) | 2022-08-28 23:31

我是发送不定长的,应该要固定容量、分批发送,通过发送一个空byte[]来表示结束。

PER10 | 园豆:8 (初学一级) | 2022-08-28 23:33

@PER10: 对,单位是byte,不定长的你可以自己约定一个协议表示结束。

寂静的羽夏 | 园豆:1781 (小虾三级) | 2022-08-29 10:04

@寂静的羽夏: 感谢感谢,分都给你。另外我找到更灵活一些的例子,不用预设内存容量:https://tieba.baidu.com/p/7993616413
具体代码就是:
(发送方)
byte[] data = new byte[] { 1, 2, 3, 4, 8, 1, 234, 11, 63, 234 };
int size = sizeof(byte) * data.Length;

        // Open shared memory
        MemoryMappedFile share_mem = MemoryMappedFile.CreateNew("shared_memory", size);
        MemoryMappedViewAccessor accessor = share_mem.CreateViewAccessor();

        // Write data to shared memory

        accessor.Write(0, size);
        accessor.WriteArray<byte>(sizeof(int), data, 0, data.Length);

        // Dispose accessor
        accessor.Dispose();

(接收方)
MemoryMappedFile share_mem = MemoryMappedFile.OpenExisting("shared_memory");
MemoryMappedViewAccessor accessor = share_mem.CreateViewAccessor();

        // Write data to shared memory
        int size = accessor.ReadInt32(0);
        byte[] data = new byte[size];
        accessor.ReadArray<byte>(sizeof(int), data, 0, data.Length);


        Console.WriteLine(data[2]);

        // Dispose resource
        accessor.Dispose();
        share_mem.Dispose();
PER10 | 园豆:8 (初学一级) | 2022-08-29 11:27
其他回答(1)
0

具体的应用场景是什么?通过redis这类内存数据库传递数据可以满足要求吗?
园子里有人发过类似的文章,你有没有试试可以用吗?

会长 | 园豆:12401 (专家六级) | 2022-08-29 11:17

一楼解决了,谢谢大哥

支持(0) 反对(0) PER10 | 园豆:8 (初学一级) | 2022-08-29 11:47

试了一些,核心问题是都没有说明内存容量是不是预估,如何动态计算数据的内存容量避免预估带来的内存浪费。

支持(0) 反对(0) PER10 | 园豆:8 (初学一级) | 2022-08-29 11:49

@PER10: 哦,我笔记好奇什么场景需要这样处理,我从来没这样做过呢

支持(0) 反对(0) 会长 | 园豆:12401 (专家六级) | 2022-08-29 12:02

@会长: 读写分离

支持(0) 反对(0) PER10 | 园豆:8 (初学一级) | 2022-08-29 13:55
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册