【问题标题】:Sockets and Streams - Mixing StreamReader and BinaryReader套接字和流 - 混合 StreamReader 和 BinaryReader
【发布时间】:2011-11-11 23:10:33
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 我在 .NET 3.5 上使用 C#,FWIW。

标签: c# .net-3.5 stream


【解决方案1】:

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

这很奇怪,为什么 BinaryReader 没有继承 TextReader 的子类,因为它的能力远远超过它。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2012-05-08
      • 2015-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-21
      • 1970-01-01
      • 2016-02-17
      相关资源
      最近更新 更多