题
我认为.NET使用某种简单的转换方法来将INT转换为字节数组?我进行了快速搜索,所有解决方案一次都在掩盖/转移一个字节,例如“好ol日”。某处是否没有TobyTearray()方法?
解决方案
byte[] bytes = BitConverter.GetBytes(i);
虽然还请注意 可能 想检查 BitConverter.IsLittleEndian
看看将要出现哪种方式!
请注意,如果您这样做 反复 您可能需要通过通过任何一班班次操作自己编写所有这些短寿命分配(>>
/ <<
),或使用 unsafe
代码。轮班操作 还 有一个优势,即他们不受您平台的端性的影响;你 总是 按照您期望的顺序获取字节。
其他提示
马克的答案当然是正确的答案。但是,由于他提到了转移操作员和不安全的代码作为替代方案。我想分享一个不太常见的选择。将结构与 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);
当然,不变的警察可能不会对最后的可能性感到兴奋:)
这可能是OT,但是如果您序列化许多原始类型或POD结构, .NET的Google协议缓冲区 可能对您有用。这解决了上面提出的Endianness问题,以及其他有用的功能。
如果您是从Google来到这里的
对较旧问题的替代答案是指约翰·斯基特(John Skeet)的库,该库具有让您直接将原始数据类型写入具有索引偏移的字节[]。远胜于 BitConverter
如果您需要性能。
只需下载来源并查看 MiscUtil.Conversion
名称空间。 EndianBitConverter.cs
为您处理一切。
这里的大多数答案要么是“不安全”,要么不是Littleendian安全。BitConverter不是Littleendian安全。因此,在一个示例中构建 这里 (请参阅pzahra的帖子)我简单地将BitConverter.islittilentian == 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
这是进入字节阵列的确切十六进制。