博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 对象、文件与二进制串(byte数组)之间的转换
阅读量:6120 次
发布时间:2019-06-21

本文共 5299 字,大约阅读时间需要 17 分钟。

hot3.png

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;

/// /// 工具类:对象与二进制流间的转换/// class ByteConvertHelper{    ///     /// 将对象转换为byte数组    ///     /// 被转换对象    /// 
转换后byte数组
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; } /// /// 将byte数组转换成对象 /// /// 被转换byte数组 ///
转换完成后的对象
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特性的结构:

/// /// 测试结构/// [Serializable]struct TestStructure{    public string A; //变量A    public char B;   //变量B    public int C;    //变量C    ///     /// 构造函数    ///     ///     ///     ///     public TestStructure(string paraA, char paraB, int paraC)    {        this.A = paraA;        this.B = paraB;        this.C = paraC;    }    ///     /// 输出本结构中内容    ///     /// 
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();}

输出为:

193913_EniJ_1425762.png

需要注意的是,用这个方式进行结构与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

/// /// 工具类:对象与二进制流间的转换/// class ByteConvertHelper{    ///     /// 将对象转换为byte数组    ///     /// 被转换对象    /// 
转换后byte数组
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; } /// /// 将byte数组转换成对象 /// /// 被转换byte数组 /// 转换成的类名 ///
转换完成后的对象
public static object Bytes2Object(byte[] buff, Type typ) { IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buff, 0); return Marshal.PtrToStructure(ptr, typ); }}

调用示例:

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

/// /// 测试结构/// struct TestStructure{    public string A; //变量A    public char B;   //变量B    public int C;    //变量C    ///     /// 构造函数    ///     ///     ///     ///     public TestStructure(string paraA, char paraB, int paraC)    {        this.A = paraA;        this.B = paraB;        this.C = paraC;    }    ///     /// 输出本结构中内容    ///     /// 
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();}

运行示例:

194511_yEp8_1425762.png

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

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

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

/// /// 工具类:文件与二进制流间的转换/// class FileBinaryConvertHelper{    ///     /// 将文件转换为byte数组    ///     /// 文件地址    /// 
转换后的byte数组
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; } /// /// 将byte数组转换为文件并保存到指定地址 /// /// byte数组 /// 保存地址 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();}

运行结果:

195722_x73a_1425762.png

END

转载于:https://my.oschina.net/Tsybius2014/blog/352409

你可能感兴趣的文章
UnrealEngine4.5 BluePrint初始化中遇到编译警告的解决办法
查看>>
User implements HttpSessionBindingListener
查看>>
抽象工厂方法
查看>>
ubuntu apt-get 安装 lnmp
查看>>
焊盘 往同一个方向增加 固定的长度方法 总结
查看>>
eclipse的maven、Scala环境搭建
查看>>
架构师之路(一)- 什么是软件架构
查看>>
jquery的冒泡和默认行为
查看>>
USACO 土地购买
查看>>
【原创】远景能源面试--一面
查看>>
B1010.一元多项式求导(25)
查看>>
10、程序员和编译器之间的关系
查看>>
前端学习之正则表达式
查看>>
配置 RAILS FOR JRUBY1.7.4
查看>>
AndroidStudio中导入SlidingMenu报错解决方案
查看>>
修改GRUB2背景图片
查看>>
Ajax异步
查看>>
好记性不如烂笔杆-android学习笔记<十六> switcher和gallery
查看>>
JAVA GC
查看>>
codeforce 599B Spongebob and Joke
查看>>