Как можно упростить преобразование порядка следования байтов в сети из BinaryReader? - PullRequest
7 голосов
/ 24 сентября 2008

System.IO.BinaryReader читает значения в формате с прямым порядком байтов.

У меня есть приложение C #, подключающееся к проприетарной сетевой библиотеке на стороне сервера. Как и следовало ожидать, серверная сторона отправляет все в порядке байтов в сети, но я считаю, что работать с этим на стороне клиента неудобно, особенно для неподписанных значений.

UInt32 length = (UInt32)IPAddress.NetworkToHostOrder(reader.ReadInt32());

- единственный способ, которым я придумал, чтобы получить правильное значение без знака из потока, но это кажется и неловким, и уродливым, и мне еще предстоит проверить, собирается ли это просто обрезать старшие значения что я должен делать забавные вещи BitConverter.

Есть ли какой-то способ, которым мне не хватает написать обертку вокруг всего этого, чтобы избежать этих уродливых преобразований при каждом чтении? Кажется, на читателе должна быть опция endian-ness, чтобы упростить подобные вещи, но я ничего не встречал.

Ответы [ 2 ]

5 голосов
/ 01 октября 2008

Нет встроенного конвертера. Вот моя оболочка (как вы можете видеть, я реализовал только те функции, которые мне нужны, но структуру довольно легко изменить по вашему вкусу):

/// <summary>
/// Utilities for reading big-endian files
/// </summary>
public class BigEndianReader
{
    public BigEndianReader(BinaryReader baseReader)
    {
        mBaseReader = baseReader;
    }

    public short ReadInt16()
    {
        return BitConverter.ToInt16(ReadBigEndianBytes(2), 0);
    }

    public ushort ReadUInt16()
    {
        return BitConverter.ToUInt16(ReadBigEndianBytes(2), 0);
    }

    public uint ReadUInt32()
    {
        return BitConverter.ToUInt32(ReadBigEndianBytes(4), 0);
    }

    public byte[] ReadBigEndianBytes(int count)
    {
        byte[] bytes = new byte[count];
        for (int i = count - 1; i >= 0; i--)
            bytes[i] = mBaseReader.ReadByte();

        return bytes;
    }

    public byte[] ReadBytes(int count)
    {
        return mBaseReader.ReadBytes(count);
    }

    public void Close()
    {
        mBaseReader.Close();
    }

    public Stream BaseStream
    {
        get { return mBaseReader.BaseStream;  }
    }

    private BinaryReader mBaseReader;
}

По сути, ReadBigEndianBytes выполняет основную работу, и это передается BitConverter. Будет определенная проблема, если вы прочитаете большое количество байтов, так как это приведет к большому выделению памяти.

1 голос
/ 24 сентября 2008

Я создал собственный BinaryReader для обработки всего этого. Он доступен как часть моей библиотеки Nextem . У него также есть очень простой способ определения бинарных структур, который, я думаю, поможет вам здесь - посмотрите Примеры.

Примечание: это только сейчас в SVN, но очень стабильно. Если у вас есть какие-либо вопросы, напишите мне на cody_dot_brocious_at_gmail_dot_com.

...