多位元組資料在記憶體中儲存順序。以 32 位元整數 0x0A0B0C0D 為例:
0A 0B 0C 0D (網路序、PowerPC)0D 0C 0B 0A (x86/x64、Intel/AMD)var stream = new MemoryStream(new byte[] { 4, 1, 0, 0 });
var reader = new BinaryReader(stream);
int i = reader.ReadInt32(); // i == 260 (小端序解讀)
BitConverter.IsLittleEndian 指示當前平台端序 (編譯期常數)truepublic static int ToInt32(byte[] value, int startIndex) {
fixed (byte* p = &value[startIndex]) {
if ((startIndex % 4) == 0) return *((int*)p); // 直接記憶體轉型 (依賴平台端序)
if (IsLittleEndian) return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}
}
static unsafe bool IsLittleEndian() {
int i = 1;
byte* b = (byte*)&i;
return b[0] == 1;
}
// Mono 使用 double 版本
static unsafe bool AmILittleEndian() {
double d = 1.0; // big: 3F F0 00... / little: 00 00 00... F0 3F
byte* b = (byte*)&d;
return b[0] == 0;
}
東京櫃 (Tokyo Tyrant) 協定要求大端序傳輸,不可直接使用 BitConverter。
static int ReadInt32(Stream s) {
var buf = new byte[4]; s.Read(buf, 0, 4);
return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); // 大端序讀取
}
static int ReadInt32(Stream s) {
var buf = new byte[4]; s.Read(buf, 0, 4);
if (BitConverter.IsLittleEndian) Array.Reverse(buf);
return BitConverter.ToInt32(buf, 0);
}
static void WriteInt32(Stream s, int value) {
var buf = BitConverter.GetBytes(value);
if (BitConverter.IsLittleEndian) Array.Reverse(buf);
s.Write(buf, 0, buf.Length);
}
讀取時先用 BinaryReader 讀入,再根據需求反轉位元組;寫入時反轉後交給 BinaryWriter。讀者可自行嘗試。