套接字和流-混合StreamReader和BinaryReader

本文关键字:StreamReader BinaryReader 混合 套接字 | 更新日期: 2023-09-27 18:14:09

我正在使用套接字连接-为了使事情更容易,我获得套接字的NetworkStream并将其包装在StreamReader中,这使得它更容易处理我的套接字从服务器接收的大部分文本内容。

然而,有时服务器会发送二进制信息,如:

TEXT
MORETEXT
500 BYTES OF BINARY DATA FOLLOWS THIS LINE
{500 bytes of binary data}

我正在用StreamReader读取文本内容,但是因为StreamReader有自己的缓冲区,这意味着StreamReader在我可以切换到BinaryReader读取500字节的二进制数据之前抓取二进制数据。

有办法解决这个问题吗?我希望能够读取文本数据,同时仍然能够读取二进制数据。

套接字和流-混合StreamReader和BinaryReader

我应该把研究做得更好;结果是BinaryReader类已经包含了字符串和字符处理方法(尽管它还需要一些,比如ReadLine,可以通过子类化它来添加)。

这是奇怪的,为什么BinaryReader不子类TextReader,因为它是比能力。

这是BinaryReader的扩展,您可以使用它来执行ReadLine和通常的BinaryReader的东西。

public class LineReader : BinaryReader
{
    private Encoding _encoding;
    private Decoder _decoder;
    const int bufferSize = 1024;
    private char[] _LineBuffer = new char[bufferSize];
    public LineReader(Stream stream, int bufferSize, Encoding encoding)
        : base(stream, encoding)
    {
        this._encoding = encoding;
        this._decoder = encoding.GetDecoder();
    }
    public string ReadLine()
    {
        int pos = 0;
        char[] buf = new char[2];
        StringBuilder stringBuffer = null;
        bool lineEndFound = false;
        while(base.Read(buf, 0, 2) > 0)
        {
            if (buf[1] == ''r')
            {
                // grab buf[0]
                this._LineBuffer[pos++] = buf[0];
                // get the ''n'
                char ch = base.ReadChar();
                Debug.Assert(ch == ''n');
                lineEndFound = true;
            }
            else if (buf[0] == ''r')
            {
                lineEndFound = true;
            }                    
            else
            {
                this._LineBuffer[pos] = buf[0];
                this._LineBuffer[pos+1] = buf[1];
                pos += 2;
                if (pos >= bufferSize)
                {
                    stringBuffer = new StringBuilder(bufferSize + 80);
                    stringBuffer.Append(this._LineBuffer, 0, bufferSize);
                    pos = 0;
                }
            }
            if (lineEndFound)
            {
                if (stringBuffer == null)
                {
                    if (pos > 0)
                        return new string(this._LineBuffer, 0, pos);
                    else
                        return string.Empty;
                }
                else
                {
                    if (pos > 0)
                        stringBuffer.Append(this._LineBuffer, 0, pos);
                    return stringBuffer.ToString();
                }
            }
        }
        if (stringBuffer != null)
        {
            if (pos > 0)
                stringBuffer.Append(this._LineBuffer, 0, pos);
            return stringBuffer.ToString();
        }
        else
        {
            if (pos > 0)
                return new string(this._LineBuffer, 0, pos);
            else
                return null;
        }
    }
}