C# 正确将字节数组(byte[])转换为BigEndian长整型(long)的实现问题
C# 大端字节序字节数组转long(与Java ByteBuffer.getLong效果一致)
问题原因
C# 内置的 BitConverter.ToInt64 默认使用当前系统的字节序,绝大多数Windows系统都是小端字节序,和Java ByteBuffer 默认的大端字节序相反。你之前直接反转整个数组的方案是错误的:Java的getLong(i)是从索引i开始取连续8个大端字节转换,反转整个数组会破坏原始字节的偏移对应关系,因此只有部分结果匹配。
方案1:使用内置BinaryPrimitives(推荐,.NET Core 2.1 / .NET 5 及以上版本)
.NET 官方已经提供了专门处理跨字节序转换的类 System.Buffers.Binary.BinaryPrimitives,直接调用大端读取方法即可:
using System.Buffers.Binary; public static long GetLongBigEndian(byte[] buffer, int startIndex) { // 从startIndex开始取8个字节,按大端序转换为long return BinaryPrimitives.ReadInt64BigEndian(buffer.AsSpan(startIndex, 8)); }
修改后的测试代码:
public static void TestLong() { byte[] testLong = new byte[]{ (byte) 0xac, (byte) 0xe0, (byte) 0x46, (byte) 0x0b, (byte) 0xff, (byte) 0x30, (byte) 0xbf, (byte) 0xbf, (byte) 0x86, (byte) 0xc3, (byte) 0xaf, (byte) 0xf4, (byte) 0x6b, (byte) 0xfe, (byte) 0xc2, }; for (int i = 0; i < (testLong.Length - 8); i++) { Console.WriteLine($"I[{i}] : {BinaryPrimitives.ReadInt64BigEndian(testLong.AsSpan(i, 8))}"); } }
运行后输出和Java结果完全一致。
方案2:兼容.NET Framework的手动实现
如果需要兼容老版本.NET Framework,没有BinaryPrimitives可用,可以手动截取对应8个字节反转后再转换:
public static long GetLongBigEndian(byte[] buffer, int startIndex) { // 截取从startIndex开始的8个字节 byte[] temp = new byte[8]; Array.Copy(buffer, startIndex, temp, 0, 8); // 如果当前系统是小端序,反转字节数组 if (BitConverter.IsLittleEndian) { Array.Reverse(temp); } return BitConverter.ToInt64(temp, 0); }
测试时直接调用该方法即可得到和Java一致的结果。
内容的提问来源于stack exchange,提问作者0x0000000000000
相关产品推荐
相关产品推荐

