Сокеты и потоки - смешивание StreamReader и BinaryReader - PullRequest
0 голосов
/ 12 ноября 2011

Я работаю с сокетным соединением - чтобы упростить процесс, я получаю сокет NetworkStream и упаковываю его в StreamReader, который облегчает работу с в основном текстовым контентом, который мой сокет получает от сервера.

Однако бывают случаи, когда сервер отправляет двоичную информацию, например так:

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

Я читаю текстовое содержимое с помощью StreamReader, но поскольку StreamReader имеет собственный буфер, это означает, что StreamReader захватываетдвоичные данные, прежде чем я смогу переключиться на BinaryReader для чтения 500 байтов двоичных данных.

Есть ли способ обойти это?Мне бы хотелось иметь возможность читать текстовые данные, в то же время читая двоичные данные.

Ответы [ 2 ]

1 голос
/ 02 марта 2012

Вот расширение 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;
        }
    }

}
1 голос
/ 13 ноября 2011

Я должен сделать свое исследование лучше;оказывается, что класс BinaryReader уже содержит методы обработки строк и символов (хотя ему нужно несколько методов, таких как ReadLine, которые можно легко добавить, используя его подклассы).

Странно, почему BinaryReader не создает подклассTextReader как он более чем способен.

...