我有一个用于RTSP通信的TCP套接字。由于数据是基于行的文本数据和字节大小块的混合,所以我将一个StreamReader附加到tcpClient.GetStream(),并在文本数据需要时调用.ReadLine()。
当我需要读取响应体时,我有一个固定的字节计数,所以我尝试使用stream.Read(),但这会阻塞,大概是因为StreamReader已经将数据读取到自己的缓冲区中了。由于这样做字符编码,它只读取一个固定数目的字符,而不是字节。
我是否可以从流中读取固定数量的字节,而不完全丢弃StreamReader,或者希望二进制数据/内容是7位安全的(而不会以UTF-8的形式解码)?另一种方法是将StreamReader的编码设置为ASCII,但这可能会破坏协议的其余部分,该协议被定义为UTF-8。
设置:
this.rtspStream = this.rtspSocket.GetStream();
this.rtspReader = new StreamReader(this.rtspStream, Encoding.UTF8);文本阅读:
string line;
while ((line = this.rtspReader.ReadLine()) != string.Empty) {
// ...
}二进制读数:
byte[] responseBody = new byte[contentLength];
this.rtspStream.Read(responseBody, 0, contentLength);发布于 2014-04-05 23:30:45
查看StreamReader源代码,不可能将StreamReader的使用与直接从流读取字节混合起来,因为StreamReader将字节读入其内部缓冲区,然后将其解码为一个可供读取的字符缓冲区。
将缓冲区大小设置为0无助于此,因为它强制将缓冲区大小至少设置为128字节。
对于我的使用,我需要彻底放弃StreamReader,用一些可以直接从流中读取的内容来替换ReadLine(),以便自己进行解析。
private string ReadLine() {
// Stringbuilder to insert the read characters in to
StringBuilder line = new StringBuilder();
// Create an array to store the maximum number of bytes for a single character
byte[] bytes = new byte[this.encoding.GetMaxByteCount(1)];
int byteCount = 0;
while (true) {
// Read the first byte
bytes[0] = (byte)this.rtspStream.ReadByte();
byteCount = 1;
// If the encoding says this isn't a full character, read until it does
while (this.encoding.GetCharCount(bytes, 0, byteCount) == 0) {
bytes[byteCount++] = (byte)this.rtspStream.ReadByte();
}
// Get the unencoded character
char thisChar = this.encoding.GetChars(bytes, 0, byteCount)[0];
// Exit if it's a new line (/r/n or /n)
if (thisChar == '\r') { continue; }
if (thisChar == '\n') { break; }
line.Append(thisChar);
}
return line.ToString();
}发布于 2014-04-02 02:08:09
我猜想您已经处理了所有的头,可能包括一个Content-Length头。我假设您现在想要阅读内容体,它可能是文本内容,也可能不是文本内容。
我认为最好的方法是以流的形式读取整个内容正文,然后在内容为文本的情况下将内容包装在StreamReader中:
List<string> lines = new List<string>();
byte[] responseBody = new byte[contentLength];
this.rtspStream.Read(responseBody, 0, contentLength);
if (contentIsText)
{
using (var memoryStream = new MemoryStream(responseBody, 0, contentLength))
{
using (var reader = new StreamReader(memoryStream))
{
string line;
while ((line = reader.ReadLine()) != string.Empty)
{
lines.Add(line);
}
}
}
// Do something with lines
}
else
{
// Do something with responseBody
}https://stackoverflow.com/questions/22799750
复制相似问题