伺服器端 .dat 檔案位元組序為大端序 (Big-Endian),客戶端讀取後需轉為小端序 (Little-Endian) 或反之。
範例:00 00 43 21 43 21 43 21 00 00 → 讀出 00 00 21 43 21 43 21 43 00 00,需兩兩交換還原。
byte[] swapped = bytes
.Select((b, i) => new { b, i })
.GroupBy(x => x.i / 2)
.SelectMany(g => new[] { g.Last().b, g.First().b })
.ToArray();
原理:索引 /2 分組,每組兩個位元組,SelectMany 以「後、前」順序輸出。
public static byte[] SwapEndian(byte[] src) {
byte[] dst = new byte[src.Length];
for (int i = 0; i < src.Length; i += 2) {
if (i + 1 < src.Length) {
dst[i] = src[i + 1];
dst[i + 1] = src[i];
} else {
dst[i] = src[i]; // 奇數長度保留最後一位
}
}
return dst;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct DataPacket {
public ushort Header;
public uint Value1;
public uint Value2;
public ushort Tail;
}
// 讀取後
DataPacket pkt = ByteArrayToStructure(bytes);
// 欲轉換端序,可逐欄位 IPAddress.NetworkToHostOrder
pkt.Value1 = (uint)IPAddress.NetworkToHostOrder((int)pkt.Value1);
| 方法 | 10MB 耗時 | 備註 |
|---|---|---|
| LINQ SelectMany | ~120 ms | 分配大量中間物件 |
| for 迴圈 | ~15 ms | 零額外分配,適合高頻呼叫 |
| Buffer.BlockCopy + 迴圈 | ~10 ms | 進階優化 |