如何将字节数组表示的Int32数组转换为c#中的Int32数组

时间:2021-06-24 16:10:09

I have an array of Int32 represented by Byte array (every 4 bytes are 1 Int32) and i want to convert them to Int32 array (with length of Byte.length/4). here is example of what i want:

我有一个由字节数组表示的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];
    }
}

But I don't want to copy them, I just want to be able to tell the compiler that it is Int32 array and not a byte array (in order to later manipulation).

但是我不想复制它们,我只想告诉编译器它是Int32数组而不是字节数组(为了以后的操作)。

I looked at this How to Convert a byte array into an int array but it convert every byte into Int32 and I want to convert every 4 bytes into Int32. I also would like to this without copy it into another array for performance.

我研究了如何将一个字节数组转换为int数组,但它将每个字节转换为Int32,我希望将每4个字节转换成Int32。我也希望不将它复制到另一个数组中以提高性能。

(we can assume that hardware is the endianness native, little endian system for little endian representation).

(我们可以假设硬件是一种天生的,小的endian表示系统。)

2 个解决方案

#1


3  

There is no direct way to convert them without copying them. You could write a linq query to return the bytes as integers, but that won't let you manipulate them.

如果不复制它们,就没有直接的方法来转换它们。您可以编写linq查询以将字节作为整数返回,但这不会让您操作它们。

One way to achieve what you want could be to wrap this in an own class:

实现你想要的东西的一种方法是把它放在自己的类中:

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); }
    }
}

With this class you can read int values from your byte array and write them back:

使用这个类,您可以从字节数组中读取int值,并将它们写回:

IntArrayOverBytes intArray = new IntArrayOverBytes(bytes);
intArray[5] = 2016;
Console.WriteLine(intArray[5]);

For full Array like functionality you would need to add some more code. For example implementing IEnumerable<int> could be useful:

对于完整的数组(如功能),您需要添加更多的代码。例如,实现IEnumerable erable - int>可能是有用的:

public int Length => bytes.Length/4;
public IEnumerator<int> GetEnumerator()
{
    for(int i=0; i<Length; i++) yield return this[i];
}

#2


1  

Here is one of the unsafe versions (needs Allow unsafe code checked in the Project Build Properties):

这里有一个不安全的版本(需要在项目构建属性中检查不安全的代码):

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 is needed to get the address of the array, and to prevent the garbage collector from relocating the array to different memory location. bytePtr + buffer.Length is the memory address after the last element in the buffer array. Adding 1 to the intPtr address moves it by 4 bytes.

为了获得数组的地址,并防止垃圾收集器将数组重新定位到不同的内存位置,需要使用fixed。bytePtr +缓冲。长度是缓冲区数组中最后一个元素之后的内存地址。向intPtr地址添加1将使其移动4字节。

My guess is that the unsafe version would be less than 2 times faster than the safe BitConverter version, so I don't think the risks are worth it. I think you can get much better performance from the suggestions in my previous answer.

我的猜测是不安全的版本将比安全的位转换器版本快不到2倍,所以我认为风险是不值得的。我认为你可以从我之前的回答中得到更好的表现。

#1


3  

There is no direct way to convert them without copying them. You could write a linq query to return the bytes as integers, but that won't let you manipulate them.

如果不复制它们,就没有直接的方法来转换它们。您可以编写linq查询以将字节作为整数返回,但这不会让您操作它们。

One way to achieve what you want could be to wrap this in an own class:

实现你想要的东西的一种方法是把它放在自己的类中:

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); }
    }
}

With this class you can read int values from your byte array and write them back:

使用这个类,您可以从字节数组中读取int值,并将它们写回:

IntArrayOverBytes intArray = new IntArrayOverBytes(bytes);
intArray[5] = 2016;
Console.WriteLine(intArray[5]);

For full Array like functionality you would need to add some more code. For example implementing IEnumerable<int> could be useful:

对于完整的数组(如功能),您需要添加更多的代码。例如,实现IEnumerable erable - int>可能是有用的:

public int Length => bytes.Length/4;
public IEnumerator<int> GetEnumerator()
{
    for(int i=0; i<Length; i++) yield return this[i];
}

#2


1  

Here is one of the unsafe versions (needs Allow unsafe code checked in the Project Build Properties):

这里有一个不安全的版本(需要在项目构建属性中检查不安全的代码):

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 is needed to get the address of the array, and to prevent the garbage collector from relocating the array to different memory location. bytePtr + buffer.Length is the memory address after the last element in the buffer array. Adding 1 to the intPtr address moves it by 4 bytes.

为了获得数组的地址,并防止垃圾收集器将数组重新定位到不同的内存位置,需要使用fixed。bytePtr +缓冲。长度是缓冲区数组中最后一个元素之后的内存地址。向intPtr地址添加1将使其移动4字节。

My guess is that the unsafe version would be less than 2 times faster than the safe BitConverter version, so I don't think the risks are worth it. I think you can get much better performance from the suggestions in my previous answer.

我的猜测是不安全的版本将比安全的位转换器版本快不到2倍,所以我认为风险是不值得的。我认为你可以从我之前的回答中得到更好的表现。