这仅是一个辅助方法帮助类,可以协助小伙伴写二进制序列化的效率,代码也还看的过去

在开始之前,我需要说明的是,如果不是必要,不要使用二进制序列化。因为很难做到版本兼容,如果写错了也不知道是哪里写错了,调试难度很大。但是对于性能的提升,其实也不大

    /// <summary>/// 二进制序列化/// </summary>interface IBinarySerializable{void Serialize(BinaryWriter binaryWriter);void Deserialize(BinaryReader binaryReader);}

这个接口用于给对象继承,如果对象继承了,那么就方便进行序列化

这是一些辅助方法

没有用到反射,需要自己手动写转换代码。注意顺序

    static class BinarySerialize{/// <summary>/// 写入 uin32 列表/// </summary>/// <param name="binaryWriter"></param>/// <param name="list"></param>public static void WriteUint32List(this BinaryWriter binaryWriter, List<uint> list){// 格式先写入列表长度,然后依次写入内容binaryWriter.Write(list.Count);foreach (var n in list){binaryWriter.Write(n);}}/// <summary>/// 读取 uint32 列表/// </summary>/// <param name="binaryReader"></param>/// <returns></returns>public static List<uint> ReadUint32List(this BinaryReader binaryReader){// 读取长度var count = binaryReader.ReadInt32();List<uint> list = new List<uint>(count);for (int i = 0; i < count; i++){list.Add(binaryReader.ReadUInt32());}return list;}/// <summary>/// 写入字符串列表/// </summary>/// <param name="binaryWriter"></param>/// <param name="stringList"></param>public static void WriteStringList(this BinaryWriter binaryWriter, List<string> stringList){// 格式先写入列表长度,然后依次写入字符串binaryWriter.Write(stringList.Count);foreach (var str in stringList){binaryWriter.Write(str);}}/// <summary>/// 写入可序列化类的列表/// </summary>/// <typeparam name="T"></typeparam>/// <param name="binaryWriter"></param>/// <param name="list"></param>public static void WriteList<T>(this BinaryWriter binaryWriter, List<T> list) where T : IBinarySerializable{// 先写入长度binaryWriter.Write(list.Count);foreach (var binarySerializable in list){binarySerializable.Serialize(binaryWriter);}}/// <summary>/// 读取可序列化类的列表/// </summary>/// <typeparam name="T"></typeparam>/// <param name="binaryReader"></param>/// <returns></returns>public static List<T> ReadList<T>(this BinaryReader binaryReader) where T : IBinarySerializable, new(){// 读取长度var count = binaryReader.ReadInt32();List<T> list = new List<T>(count);for (int i = 0; i < count; i++){T t = new T();t.Deserialize(binaryReader);list.Add(t);}return list;}/// <summary>/// 读取字符串列表/// </summary>/// <param name="binaryReader"></param>/// <returns></returns>public static List<string> ReadStringList(this BinaryReader binaryReader){// 先读取列表长度,然后依次读取字符串var count = binaryReader.ReadInt32();List<string> stringList = new List<string>(count);for (int i = 0; i < count; i++){var str = binaryReader.ReadString();stringList.Add(str);}return stringList;}/// <summary>/// 写入头信息,默认是需要固定长度的/// </summary>/// <param name="binaryWriter"></param>/// <param name="head"></param>/// <param name="headLength"></param>public static void WriteHead(this BinaryWriter binaryWriter, string head, int headLength){var headByte = StringToByteList(head);binaryWriter.WriteByteList(headByte, headLength);}/// <summary>/// 将字符串转换为 byte 其中字符串添加长度前缀/// </summary>/// <param name="str"></param>/// <returns></returns>public static byte[] StringToByteList(string str){var strByteList = Utf8.GetBytes(str);ushort byteLength = (ushort)strByteList.Length;var newLength = sizeof(ushort) + strByteList.Length;var byteList = new byte[newLength];var binaryWriter = new BinaryWriter(new MemoryStream(byteList));binaryWriter.Write(byteLength);binaryWriter.Write(strByteList);return byteList;}/// <summary>/// 写入二进制写入固定长度/// </summary>/// <param name="binaryWriter"></param>/// <param name="source"></param>/// <param name="byteCount"></param>public static void WriteByteList(this BinaryWriter binaryWriter, byte[] source, int byteCount){var byteList = new byte[byteCount];Array.Copy(source, 0, byteList, 0, Math.Min(source.Length, byteCount));binaryWriter.Write(byteList, 0, byteCount);}private static Encoding Utf8 => Encoding.UTF8;/// <summary>/// 读取固定长度的头/// </summary>/// <param name="binaryReader"></param>/// <param name="headLength"></param>/// <returns></returns>public static string ReadHead(this BinaryReader binaryReader, int headLength){var strByteLength = (ushort)binaryReader.ReadInt16();var strByteList = binaryReader.ReadBytes(strByteLength);var head = Utf8.GetString(strByteList);var readLength = headLength - sizeof(ushort) - strByteLength;binaryReader.ReadBytes(readLength);return head;}}

这里的读写 Head 也许小伙伴的业务是用不到的,我用这个方法主要是写入版本号

这是单元测试的代码,只是测试主要使用方法,边界没有测试

    [TestClass]public class BinarySerializeTests{private class FakeBinarySerialize : IBinarySerializable, IEquatable<FakeBinarySerialize>{/// <inheritdoc />public void Serialize(BinaryWriter binaryWriter){binaryWriter.Write(F1);binaryWriter.Write(F2);}/// <inheritdoc />public void Deserialize(BinaryReader binaryReader){F1 = binaryReader.ReadString();F2 = binaryReader.ReadInt32();}public string F1 { set; get; }public int F2 { set; get; }/// <inheritdoc />public bool Equals(FakeBinarySerialize other){if (ReferenceEquals(null, other)) return false;if (ReferenceEquals(this, other)) return true;return F1 == other.F1 && F2 == other.F2;}/// <inheritdoc />public override bool Equals(object obj){if (ReferenceEquals(null, obj)) return false;if (ReferenceEquals(this, obj)) return true;if (obj.GetType() != this.GetType()) return false;return Equals((FakeBinarySerialize)obj);}/// <inheritdoc />public override int GetHashCode(){unchecked{return ((F1 != null ? F1.GetHashCode() : 0) * 397) ^ F2;}}}[ContractTestCase]public void WriteUint32List(){"写入uint列表,可以读取列表内容".Test(() =>{// Arrangevar memoryStream = new MemoryStream();var binaryWriter = new BinaryWriter(memoryStream);var fakeBinarySerializeList = new List<uint>();for (int i = 0; i < 100; i++){fakeBinarySerializeList.Add((uint)i);}// ActionbinaryWriter.WriteUint32List(fakeBinarySerializeList);// AssertmemoryStream.Seek(0, SeekOrigin.Begin);var binaryReader = new BinaryReader(memoryStream);var readList = binaryReader.ReadUint32List();Equal(fakeBinarySerializeList, readList);});}[ContractTestCase]public void WriteList(){"写入列表内容,可以读取列表".Test(() =>{// Arrangevar memoryStream = new MemoryStream();var binaryWriter = new BinaryWriter(memoryStream);var fakeBinarySerializeList = new List<FakeBinarySerialize>();for (int i = 0; i < 100; i++){fakeBinarySerializeList.Add(new FakeBinarySerialize(){F1 = i.ToString(),F2 = i,});}// ActionbinaryWriter.WriteList(fakeBinarySerializeList);// AssertmemoryStream.Seek(0, SeekOrigin.Begin);var binaryReader = new BinaryReader(memoryStream);var readList = binaryReader.ReadList<FakeBinarySerialize>();Equal(fakeBinarySerializeList, readList);});}private void Equal<T>(List<T> a, List<T> b){Assert.AreEqual(a.Count, b.Count);for (int i = 0; i < a.Count; i++){Assert.AreEqual(a[i], b[i]);}}[ContractTestCase]public void WriteStringList(){"写入空字符串列表,可以读取空的列表".Test(() =>{// Arrangevar memoryStream = new MemoryStream();var binaryWriter = new BinaryWriter(memoryStream);var head = "Font Data 1.0.0";var length = 20;var test = (byte)0xF1;var stringList = new List<string>();// ActionbinaryWriter.WriteHead(head, length);binaryWriter.Write(test);binaryWriter.WriteStringList(stringList);// AssertmemoryStream.Seek(0, SeekOrigin.Begin);var binaryReader = new BinaryReader(memoryStream);var str = binaryReader.ReadHead(length);var b = binaryReader.ReadByte();var readList = binaryReader.ReadStringList();Assert.AreEqual(0, readList.Count);});"写入字符串列表,可以读取写入的值".Test(() =>{// Arrangevar memoryStream = new MemoryStream();var binaryWriter = new BinaryWriter(memoryStream);var head = "Font Data 1.0.0";var length = 20;var test = (byte)0xF1;var stringList = new List<string>(){"lindexi","doubi"};// ActionbinaryWriter.WriteHead(head, length);binaryWriter.Write(test);binaryWriter.WriteStringList(stringList);// AssertmemoryStream.Seek(0, SeekOrigin.Begin);var binaryReader = new BinaryReader(memoryStream);var str = binaryReader.ReadHead(length);var b = binaryReader.ReadByte();var readList = binaryReader.ReadStringList();});}[ContractTestCase]public void WriteHead(){"尝试写入长度小于指定长度的头,可以写入和读取".Test(() =>{// Arrangevar memoryStream = new MemoryStream();var binaryWriter = new BinaryWriter(memoryStream);var head = "Font Data 1.0.0";var length = 20;var test = (byte)0xF1;// ActionbinaryWriter.WriteHead(head, length);binaryWriter.Write(test);// AssertmemoryStream.Seek(0, SeekOrigin.Begin);var binaryReader = new BinaryReader(memoryStream);var str = binaryReader.ReadHead(length);var b = binaryReader.ReadByte();Assert.AreEqual(head, str);Assert.AreEqual(test, b);});}}

上面代码需要使用 CUnit 库的支持,才能在单元测试里面使用中文写条件

        <PackageReference Include="MSTestEnhancer" Version="1.6.0" />

我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新

如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入

如有不方便在博客评论的问题,可以加我 QQ 2844808902 交流


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


http://www.taodudu.cc/news/show-6374782.html

相关文章:

  • dotnet 进行二进制差分压缩文件
  • 自行实现比dotcore/dotnet更方便更高性能的对象二进制序列化
  • 16进制转double dotnet_IEEE 16进制字符串转化为double类型
  • 服务器发送二进制文件大小,如何从dotnet核心服务器向SignalR客户端发送二进制文件...
  • dotnet C# 将 Byte 二进制数组使用不安全代码快速转换为 int 或结构体数组
  • 1024的那些事儿
  • 啥也不是!
  • 这就是个吃饭的地方
  • 老婆这种东西
  • 抽出她裤衩里的猴皮筋做个弹弓打你们家玻璃
  • 这算是强暴吗?
  • 中国文化悲哀之一个馒头引发的强奸案
  • 我以为是个正经程序猿,结果是个中二段子精
  • 不是吧
  • 乱的都放这儿
  • 差点被一个柿子砸中 -_-
  • 也说说“小地方来的”
  • [太猛了]小宾馆里的那点破事儿[组图]
  • 啥也不是
  • 关于引用的那些事儿
  • 陕西人也太太太太太太有趣了吧!
  • 我和一个“婊子”不能不说的……
  • 论我是怎么摆烂的
  • 我要下载驱动
  • windows 10对应驱动下载和应用
  • 硬件、网卡驱动官方下载地址
  • thinkpad 最新 驱动 下载
  • HDU2059
  • SIMPACK-学习记录-Doe相关
  • [创新工具和方法论]-01- DOE课程基础知识

C# dotnet 一个看上去还能用的二进制序列化帮助类相关推荐

  1. 分分钟在自己电脑上建一个视频网站,收费电影随便看,还没广告!

    声明 iker干货 本文仅作为技术文章,不鼓励不诱导用户观看盗版视频. 第一步 分分钟在自己电脑上建一个视频网站,收费电影随便看,还没广告! 第二步 安装好软件后先切换环境,推荐使用 PHP 7.0. ...

  2. 一个看漫画、看资讯、逛论坛、听歌的神器,务必吃下这颗安利!

    感jio更新的时间怎么越来越迟了哇 在拖更的边缘徘徊emm~~  (ฅ´ω`ฅ) 但是感觉一天过的还快,太仓促了叭~ 安利一个看漫画.看资讯.逛论坛.听歌的集成工具 - 多多猫 (;¬_¬) 一个Si ...

  3. 劳资蜀道山!6个高质量免费电子书网站!我看谁还不知道

    如今,电子书轻便海量的良好移动式体验受到广大年轻读者的喜爱.但是很多人也发现,有些电子书网站很贵,某些书籍还搜不到.今天,就给大家推荐6个电子书网站,不仅免费,而且品类丰富,能帮你找到99%的电子书. ...

  4. JVM-内存与垃圾回收篇!女朋友看了都想当架构师的超详细保姆级笔记!呕心沥血之作!看完还不会你砍我!

    1. JVM与Java体系结构 1.1 Java虚拟机 Java虚拟机是一台执行Java字节码的虚拟计算机,它拥有独立的运行机制,其运行的Java字节码也未必由Java语言编译而成. JVM平台的各种 ...

  5. 盘点国内程序员不常用的热门iOS第三方库:看完,还敢自称”精通iOS开发”吗?

    综合github上各个项目的关注度与具体使用情况,涵盖功能,UI,数据库,自动化测试,编程工具等类型,看完,还敢自称"精通iOS开发"吗? https://github.com/s ...

  6. 面试挂在JVM?别慌,图文讲解JVM工作原理,看完还不懂我跪键盘

    本文转载自:面试挂在JVM?别慌,图文讲解JVM工作原理,看完还不懂我跪键盘 JDK,JRE,JVM的联系是啥? JVM Java Virtual Machine JDK Java Developme ...

  7. 学习经验总结(2)xjview学习汇总,一个看脑激活结果的好工具。

    [转载]学习经验总结(2)xjview学习汇总,一个看脑激活结果的好工具. (2014-08-09 15:57:09) 转载▼ 标签: 转载 分类: fMRI-EEG 原文地址:学习经验总结(2)xj ...

  8. RE:利用爬虫技术制作一个看动漫新番的APP

    作者:hwj3747 转载请注明 简介 在看动漫追番的时候,发现每一季度的新番都是被优酷,爱奇艺,哔哩哔哩,PPTV等各大视频厂商买了版权,导致我在手机上要装各种软件,并且很多番更是直接被广电禁掉了, ...

  9. 今天研发部来了一个看起来有50多岁的面试者

    今天研发部来了一个看起来有50多岁的面试者,后来听老大说,他是来面试电子工程师的,我们很惊讶.却又瞬间陷入了沉思,我在想我50岁的时候在干嘛?也会四处奔波到处找工作吗?或者找份领导级别的岗位还让别人觉 ...

最新文章

  1. 模型训练完才是业务的开始?说说模型监控 | CSDN博文精选
  2. 中文自然语言处理数据集:ChineseNLPCorpus(附链接)
  3. 浅析jQuery原理并仿写封装一个自己的库
  4. Oracle经验集锦
  5. 为什么mysql与eclipse_为什么这个SQL在MySQL中而不是通过Eclipse执行?
  6. Qt 视图框架示例 Colliding Mice 的翻译
  7. SAP Spartacus SimpleResponsiveBannerComponent url 的数据源
  8. php将excel导入mysql,PHP实现将EXCEL文件导入到MYSQL
  9. spring管理的类如何调用非spring管理的类
  10. iPhone软件开发新突破,真正VoIP通话
  11. 虚拟机的磁盘扩大超过2T,发现超过2T的这部分无分区
  12. 敏捷开发团队管理系列之二:程序与测试团队I
  13. 上海市XXX区信息委门户网站集成项目总结
  14. 冰点还原精灵如何安装
  15. 局域网内的ARP断网攻击
  16. 如何选择合适的CDN加速合作?关键在于这三个方面!
  17. Unity4.x UWP版本打包流程
  18. 第 2-3 课:流式布局组件详解(Flow、Wrap)
  19. 这可能是全网最详细的计算机网络面经(笔记二)
  20. 学计算机买笔记本是i5 i7,i7一定比i5强?买电脑陷阱你一定要注意了

热门文章

  1. [持续更新中]博客园开放api、还有知乎、V2EX开放接口
  2. 亚马逊、eBay、速卖通、lazada、Shopee等跨境平台,如何快速打造爆款
  3. DaVinci DM6437 中文教程
  4. 保姆级教程,一文理顺优惠券设计
  5. 亚马逊电商网红营销实战技巧分享
  6. unity3d摄像机
  7. 文本编辑器Vim/Neovim被曝任意代码执行漏洞,Notepad:兄弟等你好久了
  8. 武汉科技大学计算机研究生在哪个校区,武汉科技大学在职研究生在哪个校区
  9. java 字符串驻留_Java中的字符串驻留
  10. 向日葵远程操控的实现