首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >混合StreamReader.Read..。和Stream.Read

混合StreamReader.Read..。和Stream.Read
EN

Stack Overflow用户
提问于 2014-04-02 01:10:05
回答 2查看 370关注 0票数 0

我有一个用于RTSP通信的TCP套接字。由于数据是基于行的文本数据和字节大小块的混合,所以我将一个StreamReader附加到tcpClient.GetStream(),并在文本数据需要时调用.ReadLine()

当我需要读取响应体时,我有一个固定的字节计数,所以我尝试使用stream.Read(),但这会阻塞,大概是因为StreamReader已经将数据读取到自己的缓冲区中了。由于这样做字符编码,它只读取一个固定数目的字符,而不是字节。

我是否可以从流中读取固定数量的字节,而不完全丢弃StreamReader,或者希望二进制数据/内容是7位安全的(而不会以UTF-8的形式解码)?另一种方法是将StreamReader的编码设置为ASCII,但这可能会破坏协议的其余部分,该协议被定义为UTF-8。

设置:

代码语言:javascript
复制
this.rtspStream = this.rtspSocket.GetStream();
this.rtspReader = new StreamReader(this.rtspStream, Encoding.UTF8);

文本阅读:

代码语言:javascript
复制
string line;
while ((line = this.rtspReader.ReadLine()) != string.Empty) {
    // ...
}

二进制读数:

代码语言:javascript
复制
byte[] responseBody = new byte[contentLength];
this.rtspStream.Read(responseBody, 0, contentLength);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-05 23:30:45

查看StreamReader源代码,不可能将StreamReader的使用与直接从流读取字节混合起来,因为StreamReader将字节读入其内部缓冲区,然后将其解码为一个可供读取的字符缓冲区。

将缓冲区大小设置为0无助于此,因为它强制将缓冲区大小至少设置为128字节。

对于我的使用,我需要彻底放弃StreamReader,用一些可以直接从流中读取的内容来替换ReadLine(),以便自己进行解析。

代码语言:javascript
复制
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();
}
票数 4
EN

Stack Overflow用户

发布于 2014-04-02 02:08:09

我猜想您已经处理了所有的头,可能包括一个Content-Length头。我假设您现在想要阅读内容体,它可能是文本内容,也可能不是文本内容。

我认为最好的方法是以流的形式读取整个内容正文,然后在内容为文本的情况下将内容包装在StreamReader中:

代码语言:javascript
复制
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
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22799750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档