8

System.IO.BinaryReaderは、リトルエンディアン形式で値を読み取ります。

サーバー側のプロプライエタリネットワークライブラリに接続するC#アプリケーションがあります。サーバー側は、予想どおり、すべてをネットワークバイト順に送信しますが、クライアント側でこれを処理することは、特に符号なしの値の場合、厄介であることがわかります。

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

ストリームから正しい符号なしの値を取得するために私が思いついた唯一の方法ですが、これは厄介で醜いようです。それが高次の値を切り取るだけかどうかはまだテストしていません。楽しいBitConverterのことをするために。

すべての読み取りでこれらの醜い変換を回避するために、全体の周りにラッパーを書くことを逃している方法はありますか?このようなことを簡単にするために、リーダーにはエンディアンのオプションがあるはずのようですが、私は何も見つけていません。

4

2 に答える 2

6

コンバーターは内蔵されていません。これが私のラッパーです(ご覧のとおり、必要な機能のみを実装しましたが、構造はお好みに合わせて簡単に変更できます):

/// <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に渡されます。大量のバイトを読み取ると、大量のメモリ割り当てが発生するため、明確な問題が発生します。

于 2008-09-30T22:00:25.857 に答える
1

これらすべてを処理するカスタム BinaryReader を作成しました。私の Nextem ライブラリの一部として入手できます。また、バイナリ構造体を定義する非常に簡単な方法もあり、ここで役立つと思います。例を確認してください。

注: 現在は SVN のみですが、非常に安定しています。ご不明な点がございましたら、cody_dot_brocious_at_gmail_dot_com までメールでお問い合わせください。

于 2008-09-23T21:17:30.490 に答える