我有一个由Byte数组表示的Int32数组(每4个字节是1个Int32),我想将它们转换为Int32数组(长度为Byte.length / 4)。 这是我想要的例子:
//byte[] buffer;
for (int i=0; i<buffer.Length; i+=4)
{
Int32 temp0 = BitConverter.ToInt32(buffer, i);
temp0 += 10;
byte[] temp1 = BitConverter.GetBytes(temp0);
for (int j=0;j<4;j++)
{
buffer[i + j] = temp1[j];
}
}
但是我不想复制它们,我只是想告诉编译器它是Int32数组而不是字节数组(为了以后的操作)。
我查看了这个How to Convert a byte array into an int array,但它将每个字节转换为Int32,我希望将每个 4 字节转换为Int32。 我也想这样做而不将其复制到另一个数组中以获得性能。
(我们可以假设硬件是endianness native,little endian系统用于小端表示。)
答案 0 :(得分:3)
没有直接的方法来转换它们而不复制它们。您可以编写一个linq查询来将字节作为整数返回,但这不会让您操纵它们。
实现你想要的东西的一种方法是将它包装在一个自己的类中:
public class IntArrayOverBytes
{
private readonly byte[] bytes;
public IntArrayOverBytes(byte[] bytes)
{
this.bytes = bytes;
}
public int this[int index]
{
get { return BitConverter.ToInt32(bytes, index * 4); }
set { Array.Copy(BitConverter.GetBytes(value), 0, bytes, index * 4, 4); }
}
}
使用此课程,您可以阅读int
数组中的byte
值并将其写回:
IntArrayOverBytes intArray = new IntArrayOverBytes(bytes);
intArray[5] = 2016;
Console.WriteLine(intArray[5]);
对于完整的Array
类似功能,您需要添加更多代码。例如,实施IEnumerable<int>
可能很有用:
public int Length => bytes.Length/4;
public IEnumerator<int> GetEnumerator()
{
for(int i=0; i<Length; i++) yield return this[i];
}
答案 1 :(得分:1)
以下是项目构建属性中检查的一个不安全版本(需要Allow unsafe code):
byte[] buffer = { 255,255,255,255, 255,255,255,127 }; // little endian { -1, int.MaxValue }
unsafe
{
fixed (byte* bytePtr = buffer) // or = &buffer[0]
{
for (int* intPtr = (int*)bytePtr; intPtr < bytePtr + buffer.Length; intPtr++)
{
*intPtr += 10; //intPtr is the address, and *intPtr is the value at that address
}
}
}
Debug.Print(string.Join(", ", buffer)); //"9, 0, 0, 0, 9, 0, 0, 128" { 9, int.MinValue + 9 }
获取数组的地址需要 fixed
,并防止垃圾收集器将数组重定位到不同的内存位置。 bytePtr + buffer.Length
是buffer
数组中最后一个元素之后的内存地址。向intPtr
地址添加1可将其移动4个字节。
我的猜测是,不安全的版本比安全的BitConverter
版本快2倍,所以我不认为这些风险是值得的。我认为你可以通过my previous answer中的建议获得更好的表现。