10

C# でバイナリ ファイルを読み込もうとしていますが、問題に直面しています。私は次のように宣言しました。

public static readonly UInt32 NUMBER = 0XCAFEBABE;

次に、ファイルの最初から読み取り中に、最初の 4 バイトを読み取るように求めています (既にさまざまな方法を試しましたが、これが最も簡単です)。

UInt32 num = in_.ReadUInt32(); // in_ is a BinaryReader

4 バイトは CA、FE、BA、BE (16 進数) であることがわかっていますが、それらを変換するとUInt、異なる値が得られます。NUMBER は 3405691582、num は 3199925962 です。これも試してみました。

byte[] f2 = {0xCA, 0xFE, 0xBA, 0xBE};

実行した結果BitConverter.ToUInt32(new byte[]{0xCA, 0xFE, 0xBA, 0xBE},0)は 3199925962 です。

誰でも私を助けることができますか?

4

2 に答える 2

9

これは、マシンのエンディアンが小さいためです。BitConverter.IsLittleEndianこれを確認するには、プロパティを参照してください。

基本的に、数値は書き留める方法とは逆のバイト順で格納されます。左側に最上位の数値を書き込みますが、(リトルエンディアン) PC は左側に最下位バイトを格納します。したがって、得られる結果は実際には0xBEBAFECA(3199925962 10 進数) であり、期待したものではありません。

ビットシフト操作を使用して変換できます。

uint value = (f2[0] << 24) | (f2[1] << 16) | (f2[2] << 8) | f2[3];

IPAddress.NetworkToHostOrderI4Vが指摘したものなど、変換する方法は他にもたくさんありますf2.Reverse()

あなたの特定のコードについては、これが最も実用的だと思います:

uint num = (uint)IPAddress.NetworkToHostOrder(in_.ReadInt32());

ただし、これにより算術アンダーフローが発生する可能性があるため、/checkedコンパイラ オプションまたはcheckedキーワードで問題が発生する可能性があります(どちらもあまり一般的ではありません)。

これらの状況に対処し、よりクリーンなコードを取得したい場合は、拡張メソッドでラップします。

public static uint ReadUInt32NetworkOrder(this BinaryReader reader)
{
    unchecked
    {
        return (uint)IPAddress.NetworkToHostOrder(reader.ReadInt32());    
    }
}
于 2013-04-19T10:47:19.480 に答える
4

それがバイトオーダーと呼ばれるものです:

var result1 = BitConverter.ToUInt32(new byte[] { 0xCA, 0xFE, 0xBA, 0xBE }, 0);
//3199925962

var result2 = BitConverter.ToUInt32(new byte[] { 0xBE, 0xBA, 0xFE, 0xCA }, 0);
//3405691582
于 2013-04-19T10:48:19.617 に答える