Int到字节数组

时间:2010-11-14 07:57:48

标签: c# .net bytearray int32

我认为.net有一些简单的转换方法用于将int转换为字节数组?我做了一个快速搜索,并且所有解决方案都是位屏蔽/一次移位一个字节,如“好日子”。 在某处没有ToByteArray()方法吗?

5 个答案:

答案 0 :(得分:85)

byte[] bytes = BitConverter.GetBytes(i);

虽然也注意到可能要检查BitConverter.IsLittleEndian,看看会出现哪种方式!

请注意,如果您正在重复执行此操作,您可能希望通过任一班次操作(>> / <<自行编写,以避免所有这些短期数组分配),或使用unsafe代码。 Shift操作的优势在于它们不受平台字节序的影响; 总是按照您期望的顺序获取字节。

答案 1 :(得分:30)

马克的答案当然是正确的答案。但自从他提到移位运算符和不安全代码作为替代。我想分享一个不太常见的选择。使用具有Explicit布局的结构。这与C / C ++ union的原理类似。

这是一个可用于获取Int32数据类型的组件字节的结构示例,好的是它是双向的,您可以操作字节值并查看对Int的影响。

  using System.Runtime.InteropServices;

  [StructLayout(LayoutKind.Explicit)]
  struct Int32Converter
  {
    [FieldOffset(0)] public int Value;
    [FieldOffset(0)] public byte Byte1;
    [FieldOffset(1)] public byte Byte2;
    [FieldOffset(2)] public byte Byte3;
    [FieldOffset(3)] public byte Byte4;

    public Int32Converter(int value)
    {
      Byte1 = Byte2 = Byte3 = Byte4 = 0;
      Value = value;
    }

    public static implicit operator Int32(Int32Converter value)
    {
      return value.Value;
    }

    public static implicit operator Int32Converter(int value)
    {
      return new Int32Converter(value);
    }
  }

以上现在可以使用如下

 Int32Converter i32 = 256;
 Console.WriteLine(i32.Byte1);
 Console.WriteLine(i32.Byte2);
 Console.WriteLine(i32.Byte3);
 Console.WriteLine(i32.Byte4);

 i32.Byte2 = 2;
 Console.WriteLine(i32.Value);

当然,不变性警察可能不会对最后的可能性感到兴奋:)

答案 2 :(得分:2)

这可能是OT,但如果您要序列化大量原始类型或POD结构,Google Protocol Buffers for .Net可能对您有用。这解决了上面提到的@Marc的字节序问题,以及其他有用的功能。

答案 3 :(得分:1)

如果您来自Google

旧问题的替代答案是指John Skeet的库,它具有允许您将原始数据类型直接写入具有索引偏移量的byte []的工具。如果你需要表现,会比BitConverter好得多。

Older thread discussing this issue here

John Skeet's Libraries are here

只需下载源代码并查看MiscUtil.Conversion命名空间即可。 EndianBitConverter.cs为您处理一切。

我猜微软没有实现这个,因为.NET框架是DeFacto Safe代码。但是,成千上万的人不得不做点移动或去第三方图书馆来满足这样的基本需求,这似乎很荒谬。

答案 4 :(得分:0)

这里的大部分答案都是“不安全”和#34;或者不是LittleEndian安全。 BitConverter不是LittleEndian安全的。 所以基于here中的一个例子(参见PZahra的帖子)当BitConverter.IsLittleEndian == true

时,我只是通过反向读取字节数组来制作一个LittleEndian安全版本。
void Main(){    
    Console.WriteLine(BitConverter.IsLittleEndian); 
    byte[] bytes = BitConverter.GetBytes(0xdcbaabcdfffe1608);
    //Console.WriteLine(bytes); 
    string hexStr = ByteArrayToHex(bytes);
    Console.WriteLine(hexStr);
}

public static string ByteArrayToHex(byte[] data) 
{ 
   char[] c = new char[data.Length * 2]; 
   byte b; 
  if(BitConverter.IsLittleEndian)
  {
        //read the byte array in reverse
        for (int y = data.Length -1, x = 0; y >= 0; --y, ++x) 
        { 
            b = ((byte)(data[y] >> 4)); 
            c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
            b = ((byte)(data[y] & 0xF)); 
            c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
        }               
    }
    else
    {
        for (int y = 0, x = 0; y < data.Length; ++y, ++x) 
        { 
            b = ((byte)(data[y] >> 4)); 
            c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
            b = ((byte)(data[y] & 0xF)); 
            c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
        }
    }
    return String.Concat("0x",new string(c));
}

它返回:

True
0xDCBAABCDFFFE1608

这是进入字节数组的确切十六进制。