我正在使用套接字连接 - 为了方便起见我获得套接字的NetworkStream并将其包装在StreamReader中,这使得我更容易使用套接字从服务器接收的文本内容。
但有时服务器会发送二进制信息,如下所示:
TEXT
MORETEXT
500 BYTES OF BINARY DATA FOLLOWS THIS LINE
{500 bytes of binary data}
我正在使用StreamReader读取文本内容,但由于StreamReader有自己的缓冲区,这意味着StreamReader在切换到BinaryReader以读取500字节的二进制数据之前抓取二进制数据。
有解决方法吗?我希望能够读取文本数据,同时仍能读取二进制数据。
答案 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;
}
}
}