C# 对象、文件与二进制串(byte数组)之间的转换
来源:互联网 发布:智能对话机器人软件 编辑:程序博客网 时间:2024/06/11 13:24
C# 对象、文件与二进制串(byte数组)之间的转换
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; }}
调用示例:
假设有一个添加了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); }}
那么调用下面的代码可以完成这个结构的转换
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();}
输出为:
需要注意的是,用这个方式进行结构与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); }}
调用示例:
现有结构如下(就是比上面示例中的结构少了特性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); }}
调用下面的代码可以完成转换:
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();}
运行示例:
可以看到,数组长度仅为12,比上面示例中转换的byte[]数组短了非常多,更加节省空间
3.使用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(); }}
假设有文件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();}
运行结果:
END
- C# 对象、文件与二进制串(byte数组)之间的转换
- C# 对象、文件与二进制串(byte数组)之间的转换
- java数值类型与二进制byte数组之间的转换
- java数值类型与二进制byte数组之间的转换
- C#中byte数组与结构体之间的转换
- c# byte字节数组与string字符串之间的转换
- String 与Byte[]数组之间的转换
- C# 图片与Byte[]之间的转换
- Java 十六进制(Hex)与byte数组之间的转换
- C# 图片与字节数组(byte[])二进制相互转换,获取大小像素扩展名
- 二进制与对象之间的转换
- C#对象数组 对应js与ts之间的转换
- byte数组与文件的转换
- C#学习之byte数组与结构体之间的转换
- C#二进制数组的字符串形式转换为二进制Byte数组
- byte、二进制、十进制数值之间的转换
- C# 图片与byte[]之间以及byte[]与string之间的转换
- C# 图片与byte[]之间以及byte[]与string之间的转换
- 扩展软件包package feeds详细说明
- Java中的SoftReference
- java发送http请求
- LabVIEW关于数值显示控件增加单位的显示设置
- oracle 11g r2 RAC linux 6.4 x86_64 .
- C# 对象、文件与二进制串(byte数组)之间的转换
- 语音编码算法AMR NB , AMR WB 和AMR WB+的区别
- LEETCODE: Maximum Product Subarray
- 当json对象的key为数字时,在js中读取value的方法
- easyUI,重新渲染
- java中判断字符串是否是一个整数(转载)
- eax, ebx, ecx, edx, esi, edi, ebp, esp等都是X86 汇编语言中CPU上的通用寄存器的名称
- R: RStudio的中文读取、保存与显示
- div页面居中