【手记】注意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时指定何种编码就无所谓了。

-文毕-

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JackeyGao的博客

关于Python的20个面试题

Python 是一个高级、解释型、交互式和面向对象的脚本语言. Python 语言设计具有高度可读性的, 使用一些常见的英语词组和其他语言常用的标点符号组成的语...

1311
来自专栏mathor

TRIE(4)

 这道题的大意是我们有一个网站,然后要配置规则,决定哪些IP能访问,哪些IP不能。这些规则大概长这个样子:

1044
来自专栏Jackson0714

PHP内核之旅-3.变量

1334
来自专栏大壮

iOS runtime(理论篇)

1715
来自专栏java架构师

【SQL Server】系统学习之三:逻辑查询处理阶段-六段式

一、From阶段 针对连接说明: 1、笛卡尔积 2、on筛选器 插播:unknown=not unknuwn 缺失的值; 筛选器(on where having...

34511
来自专栏绿巨人专栏

TypeScript中的怪语法

1113
来自专栏desperate633

HashMap 与 HashTable的对比

而负载因子表示一个散列表的空间的使用程度,有这样一个公式:initailCapacity*loadFactor=HashMap的容量。

842
来自专栏我是攻城师

Apache Pig学习笔记之内置函数(三)

4154
来自专栏编程之旅

iOS设计模式之简单工厂模式

最近在看关于设计模式的书籍,开始觉得在设计程序架构之时,能够灵活运用这些设计模式,代码将变得非常具有美感。一个好的设计模式使得程序更加的灵活,容易修改,易于使用...

681
来自专栏数据结构与算法

agc016D - XOR Replace(图论 智商)

不难看出,我们把所有数$xor$起来的数替换掉之后再次$xor$,得到的一定是被替换掉的数。

885

扫码关注云+社区