dotnet C# 将 Byte 二进制数组使用不安全代码快速转换为 int 或结构体数组

我在写一个有趣的 WPF 应用,我会不断收到从硬件发过来的数据,这些数据被使用 Byte[] 数组进行传输。我想要使用最快的方法转换为我的 int 数组或者转换为结构体数组,此时可以使用不安全代码的方式转换

假定有一个二进制数组 Byte[] 是使用如下代码创建的

            var memoryStream = new MemoryStream();
            var binaryWriter = new BinaryWriter(memoryStream);
            for (int i = 0; i < 100; i++)
            {
                binaryWriter.Write(i);
            }

            memoryStream.Position = 0;

            var byteList = memoryStream.ToArray();

也就是说本质这是一个 int 数组,在获取到 byteList 时,可以如何快速转换为 int 数组使用?如果使用不安全代码,那么转换逻辑将会非常简单

            unsafe
            {
                var length = byteList.Length / sizeof(int);
                fixed (byte* bytePointer = byteList)
                {
                    int* intList = (int*) bytePointer;
                    // 这里就获取到了 int 数组,虽然这是一个指针的数组
                    for (int i = 0; i < length; i++)
                    {
                        int value = *intList;
                        Console.WriteLine(value);
                        intList++;
                    }
                }
            }

在使用不安全代码的时候,需要在项目属性生成里面勾选允许不安全代码,或者在csproj中添加下面代码

  <PropertyGroup>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>

而如果此时的 byte 数组的内容实际是某个结构体呢?例如我有一个结构体定义如下

        [StructLayout(LayoutKind.Sequential)]
        struct FooStruct
        {
            public int N1 { get; set; }
            public int N2 { get; set; }
            public int N3 { get; set; }
        }

使用这个代码写入到二进制

            for (int i = 0; i < 100; i++)
            {
                var fooStruct = new FooStruct()
                {
                    N1 = i,
                    N2 = i,
                    N3 = i
                };
                binaryWriter.Write(fooStruct.N1);
                binaryWriter.Write(fooStruct.N2);
                binaryWriter.Write(fooStruct.N3);
            }

            memoryStream.Position = 0;

            byteList = memoryStream.ToArray();

此时和上面代码差不多,只是使用对应的结构体强行转换指针就可以

            unsafe
            {
                var length = byteList.Length / sizeof(FooStruct);
                fixed (byte* bytePointer = byteList)
                {
                    var fooStructList = (FooStruct*) bytePointer;
                    for (int i = 0; i < length; i++)
                    {
                        var fooStruct = *fooStructList;

                        // 此时就获取到了结构体数组
                    }
                }
            }

通过这个方法,虽然是不安全的代码,但是能提升很多性能

本文代码放在 github 欢迎小伙伴访问

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

lindexi_gd CSDN认证博客专家 C# WPF UWP 微软最具价值专家
我是微软Windows应用开发方向的最具价值专家,欢迎访问我博客blog.lindexi.com里面有大量WPF和UWP博客
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页