套接字和流 - 混合StreamReader和BinaryReader

时间:2011-11-11 23:10:33

标签: c# .net-3.5 stream

我正在使用套接字连接 - 为了方便起见我获得套接字的NetworkStream并将其包装在StreamReader中,这使得我更容易使用套接字从服务器接收的文本内容。

但有时服务器会发送二进制信息,如下所示:

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

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

有解决方法吗?我希望能够读取文本数据,同时仍能读取二进制数据。

2 个答案:

答案 0 :(得分:1)

我应该更好地进行研究;事实证明,BinaryReader类已经包含了字符串和字符处理方法(虽然它需要一些,比如ReadLine,可以通过子类化来轻松添加)。

这很奇怪,为什么BinaryReader不会将TextReader子类化,因为它超出了它的能力。

答案 1 :(得分:1)

这是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;
        }
    }

}