1

我有下面显示的两个函数,它们是为 long 和 byte[] 值的序列化而构建的。

    public static byte[] LongToByte(long Value)
    {
        byte[] Output = new byte[8];
        Output[0] = (byte)Value;
        Output[1] = (byte)(Value >> 8);
        Output[2] = (byte)(Value >> 16);
        Output[3] = (byte)(Value >> 24);
        Output[4] = (byte)(Value >> 32);
        Output[5] = (byte)(Value >> 40);
        Output[6] = (byte)(Value >> 48);
        Output[7] = (byte)(Value >> 56);
        return Output;
    }

    public static long LongFromByte(byte[] Value)
    {
        long Output = Value[0];
        Output += ((long)Value[1] << 8);
        Output += ((long)Value[2] << 16);
        Output += ((long)Value[3] << 24);
        Output += ((long)Value[4] << 32);
        Output += ((long)Value[5] << 40);
        Output += ((long)Value[6] << 48);
        Output += ((long)Value[7] << 56);
        return Output;
    }

将使用上述方法确保字节序在任何使用它们的平台上保持不变。

还是会根据处理代码的系统的字节顺序改变两者的结果?

谢谢大家。

4

2 回答 2

2

我会避免进行自定义二进制转换,因为默认转换非常好并且有一些优化。

我建议您使用以下方法检查系统字节序:

var isLittleEndian = BitConverter.IsLittleEndian;

并且仅当当前字节序不正确时才使用自定义转换(或者您可以使用 Array.Reverse(bytes) 反转字节)

如果性能是必须的(真的很偏执),您可以实现自定义反向字节算法(使用查找表交换位,实现一个不安全的代码,以相反的顺序将字节转换为长字节(查看BitConverter 源)或只是使用按位运算符改进您当前的代码。

编辑:我检查了您的自定义序列化程序的 IL 代码(使用 [Telerik Just Decompile](http://www.telerik.com/products/decompiler.aspx 以更方便),发现从 long 到 byte 的转换是使用conv.u1 指令。

根据MSDN

如果将一种整数类型转换为另一种整数类型时发生溢出,则高位将被截断。

考虑到这一点,您的代码确实会在大端系统中产生相同的输出。

于 2012-11-07T02:05:53.047 回答
1

是的,因为您要单独提取每个字节并将其存储在数组中。因此,例如,'Output[0]' 始终是您要转换的数字的最低 8 位。如果您随后将数组写入(到磁盘文件或通过某些传输),则字节将始终按照您指定的顺序。

或者,您可以考虑使用BitConverter类文档的备注部分中描述的技术。

于 2012-11-07T01:53:05.527 回答