简体   繁体   中英

Convert byte[] to original 2d array

I've taken a 2D array of UInt16 values, and converted it to raw bytes. I would like to take those bytes and convert them back into the original 2D array, but I'm unsure of how to do this when I only have the bytes, ie, is there a way to determine the dimensions of an original array when all you have is that array converted to bytes?

Here's my code:

UInt16[,] dataArray = new UInt16[,] {
    {4, 6, 2},
    {0, 2, 0},
    {1, 3, 4}
};

long byteCountUInt16Array = dataArray.GetLength(0) * dataArray.GetLength(1) * sizeof(UInt16);

var bufferUInt16 = new byte[byteCountUInt16Array];

Buffer.BlockCopy(dataArray, 0, bufferUInt16, 0, bufferUInt16.Length);

//Here is where I try to convert the values and print them out to see if the  values are still the same:

UInt16[] originalUInt16Values = new UInt16[bufferUInt16.Length / 2];
Buffer.BlockCopy(bufferUInt16, 0, originalUInt16Values, 0, BufferUInt16.Length);
for (int i = 0; i < 5; i++)
{
     Console.WriteLine("Values---: " + originalUInt16Values[i]);
}

This code will put the bytes into a 1-dimensional array, but I would like to put them into the original 2d array. Is this possible when if all I have are the raw bytes? I'll eventually be sending these bytes via a REST call and the receiving side will only have the bytes to convert back into the original 2D array.

So... not certain exactly what you're specifications are, but you could send the dimensions (x,y) of the array as the first four bytes of your buffer. below is my crack at it. I heavily commented it so hopefully it should make sense there. Ask any questions if that code isn't clear.

  /**** SENDER *****/
  // ushort and UInt16 are the same (16-bit, 2 bytes)
  ushort[,] dataArray = new ushort[,] {
      {4, 6, 2},
      {0, 2, 0},
      {1, 3, 4}
  };

  // get the X and Y dimensions
  ushort xDim = (ushort)dataArray.GetLength(0);
  ushort yDim = (ushort)dataArray.GetLength(1);

  // Make an array for the entire 2D array and the dimension sizes
  ushort[] toSend = new ushort[xDim * yDim + 2];

  // load the dimensions into first two spots in the array
  toSend[0] = xDim;
  toSend[1] = yDim;

  // load everything else into the array
  int pos = 2;
  for (int i = 0; i < xDim; i++)
  {
    for (int j = 0; j < yDim; j++)
    {
      toSend[pos] = dataArray[i, j];
      pos += 1;
    }
  }

  // size of the array in bytes
  long byteCountUInt16Array = sizeof(ushort) * (xDim * yDim + 2);

  // create the byte buffer
  var bufferUInt16 = new byte[byteCountUInt16Array];

  // copy everything (including dimensions) into the byte beffer
  Buffer.BlockCopy(toSend, 0, bufferUInt16, 0, bufferUInt16.Length);


  /***********RECEIVER************/

  // get the dimensions from the received bytes
  ushort[] xyDim = new ushort[2];
  Buffer.BlockCopy(bufferUInt16, 0, xyDim, 0, sizeof(ushort) * 2);

  // create buffer to read the bytes as ushorts into, size it based off of
  // dimensions received.
  ushort[] readIn = new ushort[xyDim[0] * xyDim[1]];
  Buffer.BlockCopy(bufferUInt16, sizeof(ushort) * 2, readIn, 0, sizeof(ushort) * readIn.Length);

  // create 2D array to load everything into, size based off of received sizes
  ushort[,] originalUInt16Values = new ushort[xyDim[0], xyDim[1]];

  // load everything in
  int cur = 0;
  for (int i = 0; i < xyDim[0]; i++)
  {
    for (int j = 0; j < xyDim[1]; j++)
    {
      originalUInt16Values[i, j] = readIn[cur];
      cur += 1;
    }
  }

  // print everything out to prove it works
  for (int i = 0; i < xyDim[0]; i++)
  {
    for (int j = 0; j < xyDim[1]; j++)
    {
      Console.WriteLine("Values at {0},{1}: {2}", i, j, originalUInt16Values[i, j]);
    }
  }

  // uhh... keep the console open
  Console.ReadKey();

You can't get the original dimensions. Example:

8 bytes = [0, 1, 0, 2, 0, 1, 0, 2]

into array of 16 bits (2 bytes): = [1, 2, 1, 2]

into array of 64 bits (4 bytes): = [65538, 65538]

and all of these ways (1 byte, 2 bytes, 4 bytes) are valid for parsing, so you must indicate your original sizes, or at least one of them. Luckily you may send the sizes (or sizes) in the headers of the request. This may do the trick for what you want. Another way of doing this is what serial systems do: simply concat your size (or sizes) and your buffer.

size [4 bytes = Int32] + buffer [n bytes]

finally parse the first bytes to read the size and block copy starting from 1 first byte of your buffer (don't forget the offset. In the example above you should start block copying from byte number 5)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM