C# BinaryReader ReadString指定长度?
我正在开发一个解析器来接收UDP信息,解析并存储它。为此,我使用了一个C# BinaryReader ReadString指定长度?,c#,binaryreader,C#,Binaryreader,我正在开发一个解析器来接收UDP信息,解析并存储它。为此,我使用了一个BinaryReader,因为它主要是二进制信息。不过,其中一些将是字符串。对于ReadString()函数: 从当前流中读取字符串。字符串的前缀是 长度,一次编码为七位整数 我完全理解它,直到“一次七位”,我试图忽略它,直到我开始测试。我正在创建自己的字节数组,然后将其放入内存流,并尝试使用二进制读取器读取它。以下是我最初认为有效的方法: byte[] data = new byte[] { 3, 0, 0, 0, (byt
BinaryReader
,因为它主要是二进制信息。不过,其中一些将是字符串。对于ReadString()
函数:
从当前流中读取字符串。字符串的前缀是
长度,一次编码为七位整数
我完全理解它,直到“一次七位”,我试图忽略它,直到我开始测试。我正在创建自己的字节数组,然后将其放入内存流
,并尝试使用二进制读取器
读取它。以下是我最初认为有效的方法:
byte[] data = new byte[] { 3, 0, 0, 0, (byte)'C', (byte)'a', (byte)'t', }
BinaryReader reader = new BinaryReader(new MemoryStream(data));
String str = reader.ReadString();
知道一个int
是4个字节(并且游走足够长的时间来发现binarydreader
是小尾端),我传递它3的长度和相应的字母。然而,str
最终持有\0\0\0
。如果我去掉3个零,然后
byte[] data = new byte[] { 3, (byte)'C', (byte)'a', (byte)'t', }
然后它正确读取并存储Cat
。对我来说,这与文档中的长度应该是整数相冲突。现在我开始认为它们只是指没有小数点的数字,而不是数据类型int
。这是否意味着BinaryReader
永远无法读取大于127个字符的字符串(因为这将是01111111,对应于文档的7位部分)
我正在编写一个协议,在将我们的文档传递给客户之前,我需要完全了解我要做的事情。我找到了forBinaryReader
。它使用一个名为的函数,在查找该文档和文档后,我发现:
value参数的整数一次写入七位
时间,从七个最低有效位开始。高位
字节指示在此之后是否还有更多的字节要写入
一个。若该值适合七位,则只需要一个字节的空间。
如果值不适合七位,则在第一位设置高位
字节并写出。然后将该值移位七位,再移位下一位
字节被写入。重复此过程,直到完成整个整数
已经写好了
另外,拉尔夫发现,更好地显示正在发生的事情。除非他们明确地说“int”或“Int32”,否则他们只是指整数和整数 “一次7位”意味着它实现了7位长度的编码,这在一开始似乎有点混乱,但实际上相当简单。以下是一些示例值,以及它们是如何使用7位长度编码写入的:
/*
decimal value binary value -> enc byte 1 enc byte 2 enc byte 3
85 00000000 00000000 01010101 -> 01010101 n/a n/a
1,365 00000000 00000101 01010101 -> 11010101 00001010 n/a
349,525 00000101 01010101 01010101 -> 11010101 10101010 00010101
*/
上面的表格使用big-endian没有其他原因,只是我不得不选择一个,这是我最熟悉的。7位长度编码的工作方式,本质上是小端码
请注意,85写入1字节,1365写入2字节,349525写入3字节
这是同一个表格,使用字母显示每个值的位在写入输出中的使用情况(虚线是零值位,0和1是编码机制添加的,用于指示是否写入/读取后续字节)
因此,0到2^7-1(127)范围内的值将作为1字节写入,2^7(128)到2^14-1(16383)范围内的值将使用2字节,2^14(16384)到2^21-1(2097151)范围内的值将使用3字节,依此类推。BinaryReader设计用于读取使用BinaryWriter写入的内容。因此,请尝试使用BinaryWriter写出不同长度的字符串,您应该能够了解协议。但您最好了解UDP协议在不作为字符串前缀时如何向您发送数据(这是最有可能的)这一切都是徒劳的。我正在为我的工作定义协议,发送数据的代码很可能不是用C#编写的(可能是python或linux上的C),因此无法访问BinaryWriter。我使用BinaryReader来提高代码可读性,尽管我可能会放弃
ReadString
,使用4个字节作为长度,并使用ReadChars
,因此更容易实现。我对编码的看法是错误的,它使用了“Writers current Encoding”但是如果二进制流是由运行在Big-Endian机器上的程序编写的,然后由另一个运行在Little-Endian机器上的程序读取(例如,如果文件是传输的),该怎么办?我想他们错过了。我正在编写一个应用程序,其中我以Big-Endian(网络字节顺序)编写流。
/*
decimal value binary value -> enc byte 1 enc byte 2 enc byte 3
85 -------- -------- -AAAAAAA -> 0AAAAAAA n/a n/a
1,365 -------- -----BBB AAAAAAAA -> 1AAAAAAA 0---BBBA n/a
349,525 -----CCC BBBBBBBB AAAAAAAA -> 1AAAAAAA 1BBBBBBA 0--CCCBB
*/