Error in converting byte array to int array in C# - c#

I am trying to convert a byte array to an int array ad then convert the byte array back to an int array.
For converting from byte array to int array I used this code:
int[] iArray = new int[someSize];
byte[] bArray = new byte[iArray.Length * sizeof(int)];
Buffer.BlockCopy(iArray, 0,bArray, 0, bArray.Length); // This code works correctly.
But when converting from the byte array to in int array, the values in the iArray2 array becomes false when the value in the iArray array is larger than 256 (may be it is overflow, I do not know.)
// What is the error in this code?.
int iArray2 = new int[someSize];
Buffer.BlockCopy(bArray, 0, iArray2, 0, iArray2.Length);
How can I convert from byte array to int array correctly?

Buffer.BlockCopy always deals in bytes, not array units.
Therefore, when you pass iArray2.Length in the second BlockCopy() call, you're copying that many bytes, which is one quarter of your actual array.

Related

Copying arrays in c#

I am trying to copy an array in C#.
The definition of the first array is :
byte [][] a which contains 8 arrays each of size 8192 bytes.
The destination array is a 1d array of size 8192*8
Buffer.BlockCopy(a,0,b,0,8192*8)
where b is the destination array. However I keep getting Object must be an array of primitives. Does anyone know why this is happening?
That's because you don't have a single array of value, you have an array of references to arrays of values.
The byte[][] type is not the same as the byte[,] type. The first is an array of arrays (aka jagged array) while the second is a two dimensional array.
You would need to copy each array by itself:
for (int i = 0; i < a.Length; i++) {
Buffer.BlockCopy(a[i], 0, b, 8192 * i, 8192);
}
That is because your first input array is not an array of primitives. It is an array of byte[] arrays.
Buffer.BlockCopy(a(array of byte[]) , 0, b (array of byte),0,8192*8)
Fix:
Buffer.BlockCopy(a.SelectMany().ToArray(), 0, b, 0, 8192*8)
But to be honest I think you have the same result with:
var b = a.SelectMany().ToArray();

How to Convert Primitive[] to byte[]

For Serialization of Primitive Array, i'am wondering how to convert a Primitive[] to his corresponding byte[]. (ie an int[128] to a byte[512], or a ushort[] to a byte[]...)
The destination can be a Memory Stream, a network message, a file, anything.
The goal is performance (Serialization & Deserialization time), to be able to write with some streams a byte[] in one shot instead of loop'ing' through all values, or allocate using some converter.
Some already solution explored:
Regular Loop to write/read
//array = any int[];
myStreamWriter.WriteInt32(array.Length);
for(int i = 0; i < array.Length; ++i)
myStreamWriter.WriteInt32(array[i]);
This solution works for Serialization and Deserialization And is like 100 times faster than using Standard System.Runtime.Serialization combined with a BinaryFormater to Serialize/Deserialize a single int, or a couple of them.
But this solution becomes slower if array.Length contains more than 200/300 values (for Int32).
Cast?
Seems C# can't directly cast a Int[] to a byte[], or a bool[] to a byte[].
BitConverter.Getbytes()
This solution works, but it allocates a new byte[] at each call of the loop through my int[]. Performances are of course horrible
Marshal.Copy
Yup, this solution works too, but same problem as previous BitConverter one.
C++ hack
Because direct cast is not allowed in C#, i tryed some C++ hack after seeing into memory that array length is stored 4 bytes before array data starts
ARRAYCAST_API void Cast(int* input, unsigned char** output)
{
// get the address of the input (this is a pointer to the data)
int* count = input;
// the size of the buffer is located just before the data (4 bytes before as this is an int)
count--;
// multiply the number of elements by 4 as an int is 4 bytes
*count = *count * 4;
// set the address of the byte array
*output = (unsigned char*)(input);
}
and the C# that call:
byte[] arrayB = null;
int[] arrayI = new int[128];
for (int i = 0; i < 128; ++i)
arrayI[i] = i;
// delegate call
fptr(arrayI, out arrayB);
I successfully retrieve my int[128] into C++, switch the array length, and affecting the right adress to my 'output' var, but C# is only retrieving a byte[1] as return. It seems that i can't hack a managed variable like that so easily.
So i really start to think that all theses casts i want to achieve are just impossible in C# (int[] -> byte[], bool[] -> byte[], double[] -> byte[]...) without Allocating/copying...
What am-i missing?
How about using Buffer.BlockCopy?
// serialize
var intArray = new[] { 1, 2, 3, 4, 5, 6, 7, 8 };
var byteArray = new byte[intArray.Length * 4];
Buffer.BlockCopy(intArray, 0, byteArray, 0, byteArray.Length);
// deserialize and test
var intArray2 = new int[byteArray.Length / 4];
Buffer.BlockCopy(byteArray, 0, intArray2, 0, byteArray.Length);
Console.WriteLine(intArray.SequenceEqual(intArray2)); // true
Note that BlockCopy is still allocating/copying behind the scenes. I'm fairly sure that this is unavoidable in managed code, and BlockCopy is probably about as good as it gets for this.

How to remove bytes from a specific index from a byte array

I have a byte array . I need to remove the bytes at specific index and split the byte arrays. For example Say I have a byte array of length 1000 . And I need to remove the bytes from position 50 to 200 .So my expected result would be 2 byte arrays . One is 0-49 and another is 201-1000.
Is Array.RemoveAt the only way to remove the byte array with index?
Thanks in advance!
If speed is critical, you can create two new arrays and use Array.Copy() to copy the required bytes into them.
To make this easier to use, it might be more convenient to write a little extension method for arrays which extracts and returns a subset, like this (note: error handling omitted for brevity):
public static class ArrayExt
{
public static T[] Subset<T>(this T[] array, int start, int count)
{
T[] result = new T[count];
Array.Copy(array, start, result, 0, count);
return result;
}
}
Then you can use it like so (I have corrected the index from your example; you had it starting at 201, but it should have been 200):
var array1 = new byte[1000];
// ... populate array1 somehow, then extract subsets like so:
var array2 = array1.Subset( 0, 50);
var array3 = array1.Subset(200, 800);
// Now array2 and array3 are two byte arrays
// containing the required bytes.
This is probably the fastest you are likely to get.
You could use IEnumerable Take and Skip, for example
byte[] origin = new byte[200];
for(int i = 0; i < origin.Length; i++)
origin[i] = (byte)i;
byte[] first = origin.Take(50).ToArray();
byte[] second = origin.Skip(100).Take(50).ToArray();
Below code can be used to split the byte array, "index" starting index and "count" is the index count upto which index you want to split, here for your condition index=50 and count is 150;
List<byte> byteArray = array.ToList(); //array is the byte array
byteArray.RemoveRange(index, count);
Byte[] array1 = byteArray.ToArray(); //array1 is the resultant byte array
Cant you get the sub arrays like this?
byte[] array1 = array.ToList().GetRange(0, x1-1).ToArray();
byte[] array2 = array.ToList().GetRange(x2, array.Length- x2 - 1).ToArray();
where x1 and x2 is 50 and 200 in your example

C# byte[] to long and back

I want to convert a given byte array to an int. Then I want to reverse the process. That is I want to get back the original byte array from that int.
I thought something like this would have worked:
byte[] myBytes = { 0, 0, 0, 32 };
if (BitConverter.IsLittleEndian)
Array.Reverse(myBytes);
int i = BitConverter.ToInt32(myBytes, 0);
Console.WriteLine("int: {0}", i); // Output: 32
byte[] newBytes = BitConverter.GetBytes(i);
Console.WriteLine("byte array: " + BitConverter.ToString(newBytes));
// Outputs: 20-00-00-00
So it doesn't give me back the original byte array. What am I doing wrong?
You're reversing the bytes with Array.Reverse for no obvious reason - given that you're using BitConverter for both conversion to an int and from an int, you don't need the Array.Reverse call at all.
If you want to treat the byte array as big-endian and you're faced with a little-endian BitConverter, you have to reverse the array in both cases, not just one. Basically you should regard BitConverter as providing a reversible conversion, but it may not be the exact conversion you want.
You might want to use my EndianBitConverter in my MiscUtil project if you want to specify endianness for this kind of conversion.

get every nth byte/value in array

I'm looking for a smooth/fast way to retrieve every nth short in a byte array and copy it to a new array.
l = lowerbyte
u = upperbyte
My data is of the following form:
byte[] bytes= {a0l, a0u, b0l, b0u, c0l, ..., n0l, n0l, a1l, a1u, b1l, ..., nXl, nXu}
What I need is to get get n byte arrays of length X (e.g., a[0..X], b[0..X], ... or M[a..n][0..X])
I was thinking of the following two steps:
convert values to short (=> short[] shorts= { a0, b0, c0, ... n0, a1, .. nX})
by using something like
short[] shorts= new short[(int)(Math.Ceiling(bytes.Length / 2.0)];
Buffer.BlockCopy(bytes, 0, shorts, 0, bytes.Length);
retrieve every second value from shorts
I'm looking for some fast code here... something like blockcopy with skip
I am completely aware that I could use a loop - but maybe there's a better
solution to it as I need to do this task for 80MB/s...
convert it back to byte arrays (same same - using blockcopy)
byte[] arrayX = new byte[shorts.Length * 2];
Buffer.BlockCopy(shorts, 0, arrayX , 0, arrayX .Length);
Thank you so much!
I think you might as just well copy the bytes directly to the new byte array, having calculated the correct offset for each short.
Converting it all to a separate short array and back to a byte array is a waste of time IMO.

Categories