C#如何用结构体直接读取二进制文件的内容

时间:2023-01-04 08:50:10
我的结构体如下
 [StructLayout(LayoutKind.Sequential)]
        public struct BYTE_4
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] col;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct BYTE_6
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public byte[] col;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct BYTE_2_4
        {

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] //注意:这里对应一维数组[/b]    
            public BYTE_4[] row;
        }

        public struct BYTE_2_6
        {

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] //注意:这里对应一维数组[/b]    
            public BYTE_6[] row;
        }

        public struct netBaseParamStructure //网络基本参数
        {
            public BYTE_2_4 bytIP ;  //0 To 1:A网口和B网口,0 To 3:每个IP地址占用共4个字节
            public BYTE_2_4 bytMask ;   //地址掩码
            public BYTE_2_4 bytGateWay; //网关信息
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
            public byte[] ISMacAsigned;
            public BYTE_2_6 MacAsigned;//= new Byte[2, 6];/
            public Byte SNtpVer;                      
            public Byte uiencast;                     
        }


这边我是使用字符数组data先读取二进制文件,
  using (var reader = new BinaryReader(File.OpenRead(filename)))
              {
                  reader.BaseStream.Seek(0, SeekOrigin.Begin);
                  reader.Read(data, 0, 40);
              }
          //data 数组赋值给结构体
           int _StuctSize = Marshal.SizeOf(typeof(netBaseParamStructure));
            Console.WriteLine(_StuctSize);
            IntPtr _StructIntPtr = Marshal.AllocHGlobal(_StuctSize);
            Marshal.Copy(data, 0, _StructIntPtr, _StuctSize);
            object _StructObject = Marshal.PtrToStructure(_StructIntPtr, typeof(netBaseParamStructure));
            Marshal.FreeHGlobal(_StructIntPtr);
            netBaseParamStructure _Image = (netBaseParamStructure)_StructObject


我想请问如何不通过字符数组直接用结构体接受二进制文件的内容?????

7 个解决方案

#1


你的结构体定义用到了大量的MarshalAs特性,因此你只能利用Marshal类帮你转换字节数组到结构体,这个类已经非常高效了,内部实现是本地语言。
如果可以的话,你完全可以修改结构体定义,改为一个基本的Class,内部一个私有的byte数组,长度40字节。提供各种get、set操作,对数组偏移地址操作,将现在的结构体字段全部改造为类的属性来提供对外接口,而内部存储用字节数组,这样的话,读写文件就是直接把那个字节数组输出到文件或从文件加载而已,各种操作的效率都将非常高。

#2


 

引用 1 楼 qldsrx 的回复:
你的结构体定义用到了大量的MarshalAs特性,因此你只能利用Marshal类帮你转换字节数组到结构体,这个类已经非常高效了,内部实现是本地语言。
如果可以的话,你完全可以修改结构体定义,改为一个基本的Class,内部一个私有的byte数组,长度40字节。提供各种get、set操作,对数组偏移地址操作,将现在的结构体字段全部改造为类的属性来提供对外接口,而内部存储用字节数组,这样的话,读写文件就是直接把那个字节数组输出到文件或从文件加载而已,各种操作的效率都将非常高。


这两种方法差不多吧 都是通过字节数组做中间传递,难道C#里面就没有想VB里一样 直接给struct结构体读写二进制文件吗?现在有个项目是VB程序转到WINFORM,对于多维数组如果用字节数组来做文件的读取就会出现存储格式的问题。所以很纠结

#3


只能按C#提供的方法按字节读取的。

#4


不建议直接用结构体,这种读出再转换时耗时的,最好是直接操作
第二段代码你已经写了,你可以测试下直接读,和结构体转换读的差别。

最好文件是存储一类的数据类型(或者知道规则),然后读出来,或者直接需要时读

看你的代码,就是存网络连接地址信息的,没必要搞的这么复杂,直接二进制存储,转换为字符串就好,然后再解析。

#5


引用 4 楼 zixingcheng_ 的回复:
不建议直接用结构体,这种读出再转换时耗时的,最好是直接操作
第二段代码你已经写了,你可以测试下直接读,和结构体转换读的差别。

最好文件是存储一类的数据类型(或者知道规则),然后读出来,或者直接需要时读

看你的代码,就是存网络连接地址信息的,没必要搞的这么复杂,直接二进制存储,转换为字符串就好,然后再解析。



没办法啊 ,VB转换成C#,而且在其他地方有调用关系,如果不赋值给结构体,到时候不知道数组里面哪一位是哪个。。。我也纠结中,体力活

#6


那你加个解析为结构体的接口,实现之,在用的地方调用就好。

#7


楼主问题解决了吗?  最终如何处理的?

#1


你的结构体定义用到了大量的MarshalAs特性,因此你只能利用Marshal类帮你转换字节数组到结构体,这个类已经非常高效了,内部实现是本地语言。
如果可以的话,你完全可以修改结构体定义,改为一个基本的Class,内部一个私有的byte数组,长度40字节。提供各种get、set操作,对数组偏移地址操作,将现在的结构体字段全部改造为类的属性来提供对外接口,而内部存储用字节数组,这样的话,读写文件就是直接把那个字节数组输出到文件或从文件加载而已,各种操作的效率都将非常高。

#2


 

引用 1 楼 qldsrx 的回复:
你的结构体定义用到了大量的MarshalAs特性,因此你只能利用Marshal类帮你转换字节数组到结构体,这个类已经非常高效了,内部实现是本地语言。
如果可以的话,你完全可以修改结构体定义,改为一个基本的Class,内部一个私有的byte数组,长度40字节。提供各种get、set操作,对数组偏移地址操作,将现在的结构体字段全部改造为类的属性来提供对外接口,而内部存储用字节数组,这样的话,读写文件就是直接把那个字节数组输出到文件或从文件加载而已,各种操作的效率都将非常高。


这两种方法差不多吧 都是通过字节数组做中间传递,难道C#里面就没有想VB里一样 直接给struct结构体读写二进制文件吗?现在有个项目是VB程序转到WINFORM,对于多维数组如果用字节数组来做文件的读取就会出现存储格式的问题。所以很纠结

#3


只能按C#提供的方法按字节读取的。

#4


不建议直接用结构体,这种读出再转换时耗时的,最好是直接操作
第二段代码你已经写了,你可以测试下直接读,和结构体转换读的差别。

最好文件是存储一类的数据类型(或者知道规则),然后读出来,或者直接需要时读

看你的代码,就是存网络连接地址信息的,没必要搞的这么复杂,直接二进制存储,转换为字符串就好,然后再解析。

#5


引用 4 楼 zixingcheng_ 的回复:
不建议直接用结构体,这种读出再转换时耗时的,最好是直接操作
第二段代码你已经写了,你可以测试下直接读,和结构体转换读的差别。

最好文件是存储一类的数据类型(或者知道规则),然后读出来,或者直接需要时读

看你的代码,就是存网络连接地址信息的,没必要搞的这么复杂,直接二进制存储,转换为字符串就好,然后再解析。



没办法啊 ,VB转换成C#,而且在其他地方有调用关系,如果不赋值给结构体,到时候不知道数组里面哪一位是哪个。。。我也纠结中,体力活

#6


那你加个解析为结构体的接口,实现之,在用的地方调用就好。

#7


楼主问题解决了吗?  最终如何处理的?