How to convert an int[,] to byte[] in C#?
Some code will be appreciated
EDIT:
I need a function to perform the following:
byte[] FuncName (int[,] Input)
Since there is very little detail in your question, I can only guess what you're trying to do... Assuming you want to "flatten" a 2D array of ints into a 1D array of bytes, you can do something like that :
byte[] Flatten(int[,] input)
{
return input.Cast<int>().Select(i => (byte)i).ToArray();
}
Note the call to Cast : that's because multidimensional arrays implement IEnumerable but not IEnumerable<T>
It seem that you are writing the types wrong, but here is what you might be looking for:
byte[] FuncName (int[,] input)
{
byte[] byteArray = new byte[input.Length];
int idx = 0;
foreach (int v in input) {
byteArray[idx++] = (byte)v;
}
return byteArray;
}
Here's an implementation that assumes you are attempting serialization; no idea if this is what you want, though; it prefixes the dimensions, then each cell using basic encoding:
public byte[] Encode(int[,] input)
{
int d0 = input.GetLength(0), d1 = input.GetLength(1);
byte[] raw = new byte[((d0 * d1) + 2) * 4];
Buffer.BlockCopy(BitConverter.GetBytes(d0), 0, raw, 0, 4);
Buffer.BlockCopy(BitConverter.GetBytes(d1), 0, raw, 4, 4);
int offset = 8;
for(int i0 = 0 ; i0 < d0 ; i0++)
for (int i1 = 0; i1 < d1; i1++)
{
Buffer.BlockCopy(BitConverter.GetBytes(input[i0,i1]), 0,
raw, offset, 4);
offset += 4;
}
return raw;
}
The BitConverter converts primitive types to byte arrays:
byte[] myByteArray = System.BitConverter.GetBytes(myInt);
You appear to want a 2 dimensional array of ints to be converted to bytes. Combine the BitConverter with the requisite loop construct (e.g foreach) and whatever logic you want to combine the array dimensions.
Related
I want to convert a two dimensional int array to a byte array. what is the most simple way to do so? Example:
int[,] array = new int[2, 2] { { 2, 1 }, { 0, 1 } };
How can i convert array to a byte[]? On your answer, please include also the reverse function to that. (if there is a function to convert an int[,] to a byte[] please show me also how to convert a byte[] to an int[,] )
If you're asking yourself why do i need to do it: i need to send a int[,] over a TCP client to a server, then send a response to the client
PS: I thought about making a [Serializeable] class, which will contain the int[,], then serialize the class into a file and send that file, on the server side i will deserialize that file and get the array from there. but i thought that it would take a lot more resrouces to do that then just converting it to a byte[].
Thank you for your help! :)
Short answer: Buffer.BlockCopy.
public static byte[] ToBytes<T>(this T[,] array) where T : struct
{
var buffer = new byte[array.GetLength(0) * array.GetLength(1) * System.Runtime.InteropServices.Marshal.SizeOf(typeof(T))];
Buffer.BlockCopy(array, 0, buffer, 0, buffer.Length);
return buffer;
}
public static void FromBytes<T>(this T[,] array, byte[] buffer) where T : struct
{
var len = Math.Min(array.GetLength(0) * array.GetLength(1) * System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), buffer.Length);
Buffer.BlockCopy(buffer, 0, array, 0, len);
}
If you aren't afraid of using unsafe code it's really simple:
int[,] array = new int[2, 2];
//Do whatever to fill the array
byte[] buffer = new byte[array.GetLength(0) * array.GetLength(1) * sizeof(int)];
fixed (void* pArray = &array[0,0])
{
byte* pData = (byte*)pArray;
for (int buc = 0; buc < buffer.Length; buc++)
buffer[buc] = *(pData + buc);
}
This might be a simple one, but I can't seem to find an easy way to do it. I need to save an array of 84 uint's into an SQL database's BINARY field. So I'm using the following lines in my C# ASP.NET project:
//This is what I have
uint[] uintArray;
//I need to convert from uint[] to byte[]
byte[] byteArray = ???
cmd.Parameters.Add("#myBindaryData", SqlDbType.Binary).Value = byteArray;
So how do you convert from uint[] to byte[]?
How about:
byte[] byteArray = uintArray.SelectMany(BitConverter.GetBytes).ToArray();
This'll do what you want, in little-endian format...
You can use System.Buffer.BlockCopy to do this:
byte[] byteArray = new byte[uintArray.Length * 4];
Buffer.BlockCopy(uintArray, 0, byteArray, 0, uintArray.Length * 4];
http://msdn.microsoft.com/en-us/library/system.buffer.blockcopy.aspx
This will be much more efficient than using a for loop or some similar construct. It directly copies the bytes from the first array to the second.
To convert back just do the same thing in reverse.
There is no built-in conversion function to do this. Because of the way arrays work, a whole new array will need to be allocated and its values filled-in. You will probably just have to write that yourself. You can use the System.BitConverter.GetBytes(uint) function to do some of the work, and then copy the resulting values into the final byte[].
Here's a function that will do the conversion in little-endian format:
private static byte[] ConvertUInt32ArrayToByteArray(uint[] value)
{
const int bytesPerUInt32 = 4;
byte[] result = new byte[value.Length * bytesPerUInt32];
for (int index = 0; index < value.Length; index++)
{
byte[] partialResult = System.BitConverter.GetBytes(value[index]);
for (int indexTwo = 0; indexTwo < partialResult.Length; indexTwo++)
result[index * bytesPerUInt32 + indexTwo] = partialResult[indexTwo];
}
return result;
}
byte[] byteArray = Array.ConvertAll<uint, byte>(
uintArray,
new Converter<uint, byte>(
delegate(uint u) { return (byte)u; }
));
Heed advice from #liho1eye, make sure your uints really fit into bytes, otherwise you're losing data.
If you need all the bits from each uint, you're gonna to have to make an appropriately sized byte[] and copy each uint into the four bytes it represents.
Something like this ought to work:
uint[] uintArray;
//I need to convert from uint[] to byte[]
byte[] byteArray = new byte[uintArray.Length * sizeof(uint)];
for (int i = 0; i < uintArray.Length; i++)
{
byte[] barray = System.BitConverter.GetBytes(uintArray[i]);
for (int j = 0; j < barray.Length; j++)
{
byteArray[i * sizeof(uint) + j] = barray[j];
}
}
cmd.Parameters.Add("#myBindaryData", SqlDbType.Binary).Value = byteArray;
I have an array of Floats that need to be converted to a byte array and back to a float[]... can anyone help me do this correctly?
I'm working with the bitConverter class and found myself stuck trying to append the results.
The reason I'm doing this is so I can save runtime values into a IO Stream. The target storage is Azure Page blobs in case that matters. I don't care about what endian this is stored in, as long as it input matches the output.
static byte[] ConvertFloatToByteArray(float[] floats)
{
byte[] ret = new byte[floats.Length * 4];// a single float is 4 bytes/32 bits
for (int i = 0; i < floats.Length; i++)
{
// todo: stuck...I need to append the results to an offset of ret
ret = BitConverter.GetBytes(floats[i]);
}
return ret;
}
static float[] ConvertByteArrayToFloat(byte[] bytes)
{ //to do }
If you're looking for performance then you could use Buffer.BlockCopy. Nice and simple, and probably about as fast as you'll get in managed code.
var floatArray1 = new float[] { 123.45f, 123f, 45f, 1.2f, 34.5f };
// create a byte array and copy the floats into it...
var byteArray = new byte[floatArray1.Length * 4];
Buffer.BlockCopy(floatArray1, 0, byteArray, 0, byteArray.Length);
// create a second float array and copy the bytes into it...
var floatArray2 = new float[byteArray.Length / 4];
Buffer.BlockCopy(byteArray, 0, floatArray2, 0, byteArray.Length);
// do we have the same sequence of floats that we started with?
Console.WriteLine(floatArray1.SequenceEqual(floatArray2)); // True
There's the BitConverter.ToSingle(byte[] value, int startIndex) method that should help out here.
Returns a single-precision floating
point number converted from four bytes
at a specified position in a byte
array.
Your probably want something like (untested):
static float[] ConvertByteArrayToFloat(byte[] bytes)
{
if(bytes == null)
throw new ArgumentNullException("bytes");
if(bytes.Length % 4 != 0)
throw new ArgumentException
("bytes does not represent a sequence of floats");
return Enumerable.Range(0, bytes.Length / 4)
.Select(i => BitConverter.ToSingle(bytes, i * 4))
.ToArray();
}
EDIT: Non-LINQ:
float[] floats = new float[bytes.Length / 4];
for (int i = 0; i < bytes.Length / 4; i++)
floats[i] = BitConverter.ToSingle(bytes, i * 4);
return floats;
You are not moving the position when you copy the float[i] into the byte array, you should write something like
Array.Copy(BitConverter.GetBytes(float[i]),0,res,i*4);
instead of just:
ret = BitConverter.GetBytes(floats[i]);
the inverse function follow the same strategy.
static float[] ConvertByteArrayToFloat(byte[] bytes)
{
if(bytes.Length % 4 != 0) throw new ArgumentException();
float[] floats = new float[bytes.Length/4];
for(int i = 0; i < floats.Length; i++)
{
floats[i] = BitConverter.ToSingle(bytes, i*4);
}
return floats;
}
Convertion from Double[] src to Byte[] dst
can be efficiently done in C# by fixed pointers:
fixed( Double* pSrc = src)
{
fixed( Byte* pDst = dst)
{
Byte* ps = (Byte*)pSrc;
for (int i=0; i < dstLength; i++)
{
*(pDst + i) = *(ps +i);
}
}
}
How can I do the same for List src ?
I.e. how can I get fixed pointer to array Double[]
included in List ?
Thanks.
I have used these helper methods before:
byte[] GetBytesBlock(double[] values)
{
var result = new byte[values.Length * sizeof(double)];
Buffer.BlockCopy(values, 0, result, 0, result.Length);
return result;
}
double[] GetDoublesBlock(byte[] bytes)
{
var result = new double[bytes.Length / sizeof(double)];
Buffer.BlockCopy(bytes, 0, result, 0, bytes.Length);
return result;
}
An example:
List<double> myList = new List<double>(){ 1.0, 2.0, 3.0};
//to byte[]
var byteResult = GetBytesBlock(myList.ToArray());
//back to List<double>
var doubleResult = GetDoublesBlock(byteResult).ToList();
not sure what you are intending, but I think ... you want
System.Runtime.Interopservices.Marshal.StructToPtr.
You can always use the ToArray() method on the List<Double> object to get a Double[].
You can use reflection to get the reference to the private T[] _items field, in the List instance.
Warning: In your code snippet, you need to make sure dstLength is the minimum of dst and src lengths in bytes, so that you don't try to copy more bytes than what are available. Probably you do so by creating dst with exactly the needed size to match the src, but your snippet doesn't make it clear.
Use the List<T>.ToArray() method and operate on the resulting array.
This might work, but you will have a data loss- content of the array will be 3 and 34 .
List<double> list = new List<double>();
list.Add(Math.PI);
list.Add(34.22);
byte[] arr = (from l in list
select (byte)l).ToArray<byte>();
Why don't you just access the list as usual?
List<double> list = new List<double>();
list.Add(Math.PI);
list.Add(34.22);
byte[] res = new byte[list.Count * sizeof(double)];
unsafe
{
fixed (byte* pres = res)
{
for (int i = 0; i < list.Count; i++)
{
*(((double*)pres) + i) = list[i];
}
}
}
I haven't tested it thoroughly and i seldomly need unsafe code, but it seems to work fine.
Edit: here is another (imo preferable) solution, without unsafe code:
int offset = 0;
for (int i = 0; i < list.Count; i++)
{
long num = BitConverter.DoubleToInt64Bits(list[i]);
for (int j = 0; j < 8; j++)
{
res[offset++] = (byte)num;
num >>= 8;
}
}
I want to do the equivalent of this:
byte[] byteArray;
enum commands : byte {one, two};
commands content = one;
byteArray = (byte*)&content;
yes, it's a byte now, but consider I want to change it in the future? how do I make byteArray contain content? (I don't care to copy it).
To convert any value types (not just primitive types) to byte arrays and vice versa:
public T FromByteArray<T>(byte[] rawValue)
{
GCHandle handle = GCHandle.Alloc(rawValue, GCHandleType.Pinned);
T structure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
handle.Free();
return structure;
}
public byte[] ToByteArray(object value, int maxLength)
{
int rawsize = Marshal.SizeOf(value);
byte[] rawdata = new byte[rawsize];
GCHandle handle =
GCHandle.Alloc(rawdata,
GCHandleType.Pinned);
Marshal.StructureToPtr(value,
handle.AddrOfPinnedObject(),
false);
handle.Free();
if (maxLength < rawdata.Length) {
byte[] temp = new byte[maxLength];
Array.Copy(rawdata, temp, maxLength);
return temp;
} else {
return rawdata;
}
}
The BitConverter class might be what you are looking for. Example:
int input = 123;
byte[] output = BitConverter.GetBytes(input);
If your enum was known to be an Int32 derived type, you could simply cast its values first:
BitConverter.GetBytes((int)commands.one);
You can use the BitConverter.GetBytes method to do this.
For anyone who's interested in how it works without using BitConverter you can do it like this:
// Convert double to byte[]
public unsafe byte[] pack(double d) {
byte[] packed = new byte[8]; // There are 8 bytes in a double
void* ptr = &d; // Get a reference to the memory containing the double
for (int i = 0; i < 8; i++) { // Each one of the 8 bytes needs to be added to the byte array
packed[i] = (byte)(*(UInt64 *)ptr >> (8 * i)); // Bit shift so that each chunk of 8 bits (1 byte) is cast as a byte and added to array
}
return packed;
}
// Convert byte[] to double
public unsafe double unpackDouble(byte[] data) {
double unpacked = 0.0; // Prepare a chunk of memory ready for the double
void* ptr = &unpacked; // Reference the double memory
for (int i = 0; i < data.Length; i++) {
*(UInt64 *)ptr |= ((UInt64)data[i] << (8 * i)); // Get the bits into the right place and OR into the double
}
return unpacked;
}
In reality it's much easier and safer to use BitConverter but it's fun to know!