我有一个字阵列,我读在从NetworkStream.首两字节讲的长度分组,并随后的分组是读到的一个字节列的长度。该数据在,我需要读NetworkStream/字节列有一个数字符串,即变量的数据的长度终止通过新的线字,和一些固定的宽度等领域的字节和渴望.因此,事情是这样的:

// I would have delimited these for clarity but I didn't want
// to imply that the stream was delimited because it's not.
StringbyteStringStringbytebytebytelonglongbytelonglong

我知道(而有某些人所说的)的数据的格式分组,来了,我需要做的就是阅读一个"线"的每个字符串值,但读一个固定字节数字节和渴望.迄今为止,我的提议的解决方案是以使用 while 环读字节到一个临时字阵列,直到有一个换行符。然后,转换成字节到一串。这似乎缺憾到我,但我看不到另一个明显的方式。我意识到我可以用 StreamReader.ReadLine() 但是,这将涉及另一个流和我已经有一个 NetworkStream.但如果这是更好的解决方案,我会给它一个镜头。

其他选项我认为是有我的后台团队编写一个字节或者两对于那些字符串的价值观'的长度,这样我就可以读取所长然后读取串的基础上的长度的规定。

所以,你可以看到,我有一些选择如何去关于这一点,我喜欢你的输入关于什么你会认为最好的方式来做到这一点。这里的代码,我们现在对于阅读在整个分组作为一串。下一个步骤是打出来的各个领域的分组和执行实际的编程工作需要做,创造对象,更新UI,等等。基于数据分组。

string line = null;  
while (stream.DataAvailable)
{  
    //Get the packet length;  
    UInt16 packetLength = 0;  
    header = new byte[2];  
    stream.Read(header, 0, 2);  
    // Need to reverse the header array for BitConverter class if architecture is little endian.  
    if (BitConverter.IsLittleEndian)
        Array.Reverse(header);  
    packetLength = BitConverter.ToUInt16(header,0);

    buffer = new byte[packetLength];
    stream.Read(buffer, 0, BitConverter.ToUInt16(header, 0));
    line = System.Text.ASCIIEncoding.ASCII.GetString(buffer);
    Console.WriteLine(line);
}
有帮助吗?

解决方案

我个人会

  1. 把一个Int16在开始 串的,所以你知道多长时间 他们要,
  2. 使用IO.BinaryReader类 做阅读,它会"读",整数, 串,chars等到例如可变BinReader.ReadInt16()将宣读两个字节,返回int16他们表示,移动两个字节的流

希望这会有所帮助。

P.S.小心使用ReadString方法,假定该字符串的前面添加自定义7点整数,即它是由BinaryWriter类。以下是这个 CodeGuru

该BinaryWriter类具有两个方法 为编写:超载 写()方法和符() 法。前写的字符串 作为一个字节流的根据 编码的类使用。的 符()方法还使用 指定编码,但它的前缀 串的流字节的 实际长串。这样的 作为前缀串回读通过 BinaryReader.ReadString().

有趣的事情有关的长度 它的价值,因为几个字节作为可能的 是用来保持这个尺寸, 储存作为一种类型称为一个7位 编码的整数。如果长度符合 7位数的一个字节的使用,如果它是 高于这个那么高的点上 第一个字节设定和第二 字节是通过转移价值 7位。这个是重复的 连续字节,直到没 足够的字节举行的价值。此 机制被用来确保 长度不会成为一个 大部分大小取 由serialized string.BinaryWriter和BinaryReader有 方法阅读和书写的7位 编码整数,但他们 保护和所以你可以用它们只 如果你从这些课程。

其他提示

我会去与长-前缀的弦。它会让你的生活简单得多,它意味着你可以代表串行符。一些评论在你的代码是:

  • 不要使用流。DataAvailable.只是因为没有可用数据 现在 并不意味着你已经读结束流。
  • 除非你绝对肯定你永远不需要的案文超出了ASCII、不使用用ASCIIEncoding.
  • 不要假设,流。读读取所有的数据要求。 总是 检查返回的价值。
  • BinaryReader让这一切更容易(包括长度为前缀的串和阅读这一循环,直到它的读什么你要求它)
  • 你打电话BitConverter.ToUInt16两次相同的数据。为什么?
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top