Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# BinaryReader ReadString指定长度?_C#_Binaryreader - Fatal编程技术网

C# BinaryReader ReadString指定长度?

C# BinaryReader ReadString指定长度?,c#,binaryreader,C#,Binaryreader,我正在开发一个解析器来接收UDP信息,解析并存储它。为此,我使用了一个BinaryReader,因为它主要是二进制信息。不过,其中一些将是字符串。对于ReadString()函数: 从当前流中读取字符串。字符串的前缀是 长度,一次编码为七位整数 我完全理解它,直到“一次七位”,我试图忽略它,直到我开始测试。我正在创建自己的字节数组,然后将其放入内存流,并尝试使用二进制读取器读取它。以下是我最初认为有效的方法: byte[] data = new byte[] { 3, 0, 0, 0, (byt

我正在开发一个解析器来接收UDP信息,解析并存储它。为此,我使用了一个
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位部分)

我正在编写一个协议,在将我们的文档传递给客户之前,我需要完全了解我要做的事情。

我找到了for
BinaryReader
。它使用一个名为的函数,在查找该文档和文档后,我发现:

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
*/