C 对象 文件与二进制串(byte数组)之间的转换

本文介绍了C#中如何将对象转换为byte数组以及文件与byte数组之间的转换,包括使用IFormatter的Serialize和Deserialize进行序列化与反序列化,运用Marshal类的StructureToPtr和PtrToStructure函数,以及使用FileStream进行文件操作。内容涵盖了对象序列化、内存管理和文件I/O的相关知识。

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

                       

1.关于本文

在使用C#下的TCP(类TcpClient)、UDP(类UdpClient)协议传输信息时,都需要将信息转换为byte类型的数组进行发送。本文实现了两种object与byte数组的转换和一种文件与byte数组转换的方式。基础类型的数据,可以用BitConverter类中的函数进行转换。

2.object与byte[]的相互转换:使用IFormatter的Serialize和Deserialize进行序列化与反序列化

实现这个功能,需要先引用三个命名空间:System.IO、System.Runtime.Serialization、System.Runtime.Serialization.Formatters.Binary;

/// <summary>/// 工具类:对象与二进制流间的转换/// </summary>class ByteConvertHelper{    /// <summary>    /// 将对象转换为byte数组    /// </summary>    /// <param name="obj">被转换对象</param>    /// <returns>转换后byte数组</returns>    public static byte[] Object2Bytes(object obj)    {        byte[] buff;        using (MemoryStream ms = new MemoryStream())        {            IFormatter iFormatter = new BinaryFormatter();            iFormatter.Serialize(ms, obj);            buff = ms.GetBuffer();        }        return buff;    }    /// <summary>    /// 将byte数组转换成对象    /// </summary>    /// <param name="buff">被转换byte数组</param>    /// <returns>转换完成后的对象</returns>    public static object Bytes2Object(byte[] buff)    {        object obj;        using (MemoryStream ms = new MemoryStream(buff))        {            IFormatter iFormatter = new BinaryFormatter();            obj = iFormatter.Deserialize(ms);        }        return obj;    }}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

调用示例:

假设有一个添加了Serializable特性的结构:

/// <summary>/// 测试结构/// </summary>[Serializable]struct TestStructure{    public string A; //变量A    public char B;   //变量B    public int C;    //变量C    /// <summary>    /// 构造函数    /// </summary>    /// <param name="paraA"></param>    /// <param name="paraB"></param>    /// <param name="paraC"></param>    public TestStructure(string paraA, char paraB, int paraC)    {        this.A = paraA;        this.B = paraB;        this.C = paraC;    }    /// <summary>    /// 输出本结构中内容    /// </summary>    /// <returns></returns>    public string DisplayInfo()    {        return string.Format("A:{0};B:{1};C:{2}", this.A, this.B, this.C);    }}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

那么调用下面的代码可以完成这个结构的转换

static void Main(string[] args){    TestStructure tsA = new TestStructure("1234", '5', 6);    byte[] bytTemp = ByteConvertHelper.Object2Bytes(tsA);    Console.WriteLine("数组长度:" + bytTemp.Length);    TestStructure tsB = (TestStructure)ByteConvertHelper.Bytes2Object(bytTemp);    Console.WriteLine(tsB.DisplayInfo());    Console.ReadLine();}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

输出为:

输出

需要注意的是,用这个方式进行结构与byte数组间的转换,结构或类必须有Serializable特性。否则会有异常(SerializationException):“程序集 “XXX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null” 中的类型 “XXX.XXX” 未标记为可序列化”

另外,这个方式生成的byte数组长度较大

3.使用Marshal类的StructureToPtr与PtrToStructure函数对object与byte数组进行转换

实现这个功能,需要先引用命名空间:System.Runtime.InteropServices

/// <summary>/// 工具类:对象与二进制流间的转换/// </summary>class ByteConvertHelper{    /// <summary>    /// 将对象转换为byte数组    /// </summary>    /// <param name="obj">被转换对象</param>    /// <returns>转换后byte数组</returns>    public static byte[] Object2Bytes(object obj)    {        byte[] buff = new byte[Marshal.SizeOf(obj)];        IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buff, 0);        Marshal.StructureToPtr(obj, ptr, true);        return buff;    }    /// <summary>    /// 将byte数组转换成对象    /// </summary>    /// <param name="buff">被转换byte数组</param>    /// <param name="typ">转换成的类名</param>    /// <returns>转换完成后的对象</returns>    public static object Bytes2Object(byte[] buff, Type typ)    {        IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buff, 0);        return Marshal.PtrToStructure(ptr, typ);    }}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

调用示例:

现有结构如下(就是比上面示例中的结构少了特性Serializable):

/// <summary>/// 测试结构/// </summary>struct TestStructure{    public string A; //变量A    public char B;   //变量B    public int C;    //变量C    /// <summary>    /// 构造函数    /// </summary>    /// <param name="paraA"></param>    /// <param name="paraB"></param>    /// <param name="paraC"></param>    public TestStructure(string paraA, char paraB, int paraC)    {        this.A = paraA;        this.B = paraB;        this.C = paraC;    }    /// <summary>    /// 输出本结构中内容    /// </summary>    /// <returns></returns>    public string DisplayInfo()    {        return string.Format("A:{0};B:{1};C:{2}", this.A, this.B, this.C);    }}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

调用下面的代码可以完成转换:

static void Main(string[] args){    TestStructure tsA = new TestStructure("1234", '5', 6);    byte[] bytTemp = ByteConvertHelper.Object2Bytes(tsA);    Console.WriteLine("数组长度:" + bytTemp.Length);    TestStructure tsB = (TestStructure)ByteConvertHelper.Bytes2Object(        bytTemp, Type.GetType("ByteConverter2.TestStructure"));    Console.WriteLine(tsB.DisplayInfo());    Console.ReadLine();}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

运行示例:
示例

可以看到,数组长度仅为12,比上面示例中转换的byte[]数组短了非常多,更加节省空间

4.使用FileStream将文件与byte数组相互转换

实现这个功能,需要先引用命名空间:System.IO

/// <summary>/// 工具类:文件与二进制流间的转换/// </summary>class FileBinaryConvertHelper{    /// <summary>    /// 将文件转换为byte数组    /// </summary>    /// <param name="path">文件地址</param>    /// <returns>转换后的byte数组</returns>    public static byte[] File2Bytes(string path)    {        if(!File.Exists(path))        {            return new byte[0];        }        FileInfo fi = new FileInfo(path);        byte[] buff = new byte[fi.Length];        FileStream fs = fi.OpenRead();        fs.Read(buff, 0, Convert.ToInt32(fs.Length));        fs.Close();        return buff;    }    /// <summary>    /// 将byte数组转换为文件并保存到指定地址    /// </summary>    /// <param name="buff">byte数组</param>    /// <param name="savepath">保存地址</param>    public static void Bytes2File(byte[] buff, string savepath)    {        if (File.Exists(savepath))        {            File.Delete(savepath);        }        FileStream fs = new FileStream(savepath, FileMode.CreateNew);        BinaryWriter bw = new BinaryWriter(fs);        bw.Write(buff, 0, buff.Length);        bw.Close();        fs.Close();    }}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

假设有文件test.txt,调用下面代码可以将test.txt写到byte数组中,并将这个byte数组的内容写入到文件output.txt里

static void Main(string[] args){    byte[] bytTemp = FileBinaryConvertHelper.File2Bytes("test.txt");    Console.WriteLine("数组长度:" + bytTemp.Length);    FileBinaryConvertHelper.Bytes2File(bytTemp, "output.txt");    Console.WriteLine("输出完成");    Console.ReadLine();}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

运行结果:
结果

END

文章转载自C# 对象、文件与二进制串(byte数组)之间的转换,感谢“北风其凉”提供好文章

           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow
这里写图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值