C# 从字节数组读取行(不将字节数组转换为字符串)
我有一个从网络流中读取的字节数组。前两个字节告诉后面的数据包的长度,然后数据包被读入该长度的字节数组。我需要从NetworkStream/字节数组中读取的数据有几个字符串,即以新行字符结尾的可变长度数据,以及一些固定宽度的字段,如字节和长度。比如说:C# 从字节数组读取行(不将字节数组转换为字符串),c#,.net,bytearray,networkstream,C#,.net,Bytearray,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. St
// 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
。但如果这是更好的解决方案,我会试试看
我考虑过的另一个选择是让我的后端团队为那些字符串值的长度写一两个字节,这样我就可以读取长度,然后根据指定的长度读取字符串
<> P>所以,正如你所看到的,我有一些选择来讨论这个问题,我想输入你认为最好的方法。下面是我现在所拥有的代码,用于将整个数据包作为字符串读取。下一步是分解数据包的各个字段,并根据数据包中的数据进行实际的编程工作,创建对象、更新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);
}
我个人会的
我会使用长度前缀字符串。这将使你的生活简单得多,这意味着你可以用换行符来表示字符串。不过,对您的代码有一些评论:
- 不要使用Stream.DataAvailable。现在没有可用的数据并不意味着您已经读取了流的末尾
- 除非您绝对确定永远不需要ASCII以外的文本,否则不要使用ASCII编码
- 不要假设Stream.Read将读取您要求它读取的所有数据。始终检查返回值
- BinaryReader使这方面的工作变得更加容易(包括长度前缀字符串和循环读取,直到它读取您要求它读取的内容)
- 对同一数据调用BitConverter.ToUInt16两次。为什么?