zoukankan      html  css  js  c++  java
  • 【手记】注意BinaryWriter写string的小坑——会在string前加上长度前缀length-prefixed

    之前以为BinaryWriter写string会严格按构造时指定的编码(不指定则是无BOM的UTF8)写入string的二进制,如下面的代码:

    //将字符串"a"写入流,再拿到流的字节组data
    using (var ms = new MemoryStream())
    {
        using (var bw = new BinaryWriter(ms))
        {
            bw.Write("a");
        }
        byte[] data = ms.ToArray();
    }

    因为字母a的utf8编码是97,所以我预期data只有1个元素且值为97,而实际上,data有两个元素,依次为1、97,显然97代表a,但前面的1是什么鬼,再试其它字符串,仍然会在前面多出1个甚至多个字节,值也比较飘忽,总之就是bw并没有老老实实地【只】写入string的二进制,而是加了些料,这在严格要求字节正确的场景会出问题,如http请求体,服务器会对这些多出来的字节表示懵逼。遂搜索一番,发现MSDNstackoverflow早有提到,前面多出来的字节实际上是表示string的长度,叫长度前缀(length-prefixed),据SO某答主的说法,这是供BinaryReader的ReadString方法用,知道长度,它才知道要读取到哪里。所以如果流的读取方不是BinaryReader,这些长度前缀就是多余甚至是有害的,这种情况下就不能使用BinaryWriter.Write(string)方法,要写入干净的string二进制,可以这样:

    bw.Write(Encoding.UTF8.GetBytes("a"));//按需选用正确的编码

    即先用具体编码得到string的字节组,再用BinaryWriter.Write(byte[])写入该字节组,当然构造bw时指定何种编码就无所谓了。

    -文毕-

  • 相关阅读:
    设计模式外观模式
    SQL Server高级查询
    电脑双屏下如何设置程序在第二屏幕运行
    Vistual Studio自带的计划任务功能
    SQL Server定时创建动态表
    访问网站出现空白页面的原因和解决方法
    微软老将Philip Su的离职信:回首12年职场生涯的心得和随笔
    SQL Server更改字段名
    刷新本页与父页的两条代码
    色彩感情
  • 原文地址:https://www.cnblogs.com/ahdung/p/6226199.html
Copyright © 2011-2022 走看看