C#字符串字节的获取

今天偶然发现一个问题——字符串字节获取的方式不同会导致获取的结果不一样。

定义如下方法,用于获取字符串的字节:

 1 static byte[] GetBytes(string data)
 2 {
 3     using (MemoryStream ms = new MemoryStream())
 4     {
 5         using (BinaryWriter bw = new BinaryWriter(ms))
 6         {
 7             bw.Write(data);
 8 
 9         }
10         return ms.ToArray();
11     }
12 }

以下方式也可以获取字符串对应的字节:

1 UTF8Encoding encoding = new UTF8Encoding();
2 int len1 = encoding.GetBytes(name).Length;

测试:

 1 static void Main(string[] args)
 2 {
 3     string name = "123";
 4 
 5     UTF8Encoding encoding = new UTF8Encoding();
 6     int len1 = encoding.GetBytes(name).Length;
 7 
 8     int len2 = GetBytes(name).Length;
 9 
10     Console.WriteLine($"len1 = {len1} \n\nlen2 = {len2}");
11 
12     Console.ReadKey();
13 }

输出:

值不一样,为什么?

BinaryWriter 并没有正常地写入string的二进制,而是加了点额外的信息,这在严格要求字节正确的场景下会出问题,如http请求体,服务器会对这些多出来的字节表示懵逼。前面多出来的字节实际上是表示string的长度,叫长度前缀(length-prefixed)MSDN,据SO某答主的说法,这是供BinaryReader的ReadString方法用,知道长度,它才知道要读取到哪里。所以如果流的读取方不是BinaryReader,这些长度前缀就是多余甚至是有害的,这种情况下就不能使用BinaryWriter.Write(string)方法。要想安全地获取字符串的字节数据用UTF8Encoding的方式。

感谢这位老哥的文章

posted @ 2022-02-11 19:50  小·糊涂仙  阅读(1221)  评论(0编辑  收藏  举报