0

I am trying to download a list of byte arrays but the type is byte[][] which is then causing an issue when trying to create the file because it is expecting byte[]

byte[][] imgdata = image.ImageByteArrayList;
using (FileStream file = new FileStream(FileNameLocation, FileMode.Create, System.IO.FileAccess.Write))
{
    file.Write(imgdata, 0, imgdata.Length); //error here
    file.Flush();
    file.Close();
    file.Dispose();
}

Is there a way to convert byte[][] to byte[]? Or is there another way to download?

user123456789
  • 1,914
  • 7
  • 44
  • 100
  • If you are trying to download image from web, check this post: https://stackoverflow.com/questions/307688/how-to-download-a-file-from-a-url-in-c – Piotr P Nov 07 '19 at 12:30
  • Do you want to save a standard image file format or a custom? So what is the format (you need to project the 2 dimentional array in one dimension `[x,y => z = x + y * width]`)? Else can you use System.Draw.Image.Save? –  Nov 07 '19 at 12:32
  • Where did you get `image.ImageByteArrayList` from and what format is it in? – preciousbetine Nov 07 '19 at 12:42
  • @PiotrP I have edited my question - image was the wrong word to use.. It is a list of byte arrays that I will download and create a file from probably in PDF format – user123456789 Nov 07 '19 at 16:11
  • @preciousbetine it is coming from an API call so I have no control over the format. It is a list of byte arrays – user123456789 Nov 07 '19 at 16:12
  • @OlivierRogier it is actually a list of byte arrays – user123456789 Nov 07 '19 at 16:21
  • 1
    @user123456789 I understand, sorry, indeed, each rows have different size because of jagged. So you need to create a custom file format where you save for each row the size of the associated byte array. If your question is *How to save a jagged array and load it back?*, please update the title and the body. –  Nov 07 '19 at 16:46

2 Answers2

0

JaggedArrayHelper class to save and load jagged array of byte[][]

static public class JaggedArrayHelper
{
  static public void Save(string filename, byte[][] array)
  {
    using ( var file = new FileStream(filename, FileMode.Create, FileAccess.Write) )
    {
      foreach ( var row in array )
      {
        var sizeRow = BitConverter.GetBytes(row.Length);
        file.Write(sizeRow, 0, sizeRow.Length);
        file.Write(row, 0, row.Length);
      }
      file.Flush();
      file.Close();
    }
  }
  static public byte[][] Load(string filename)
  {
    var array = new byte[0][];
    using ( var file = new FileStream(filename, FileMode.Open, FileAccess.Read) )
    {
      int countRead;
      int countItems;
      int sizeInt = sizeof(int);
      var sizeRow = new byte[sizeInt];
      while ( true )
      {
        countRead = file.Read(sizeRow, 0, sizeInt);
        if ( countRead != sizeInt )
          break;
        countItems = BitConverter.ToInt32(sizeRow, 0);
        var data = new byte[countItems];
        countRead = file.Read(data, 0, countItems);
        if ( countRead != countItems )
          break;
        Array.Resize(ref array, array.Length + 1);
        array[array.Length - 1] = data;
      }
      file.Close();
    }
    return array;
  }
}

Test

static void TestJaggedArray()
{
  string filename = "c:\\test.bin";

  byte[][] data = new byte[4][];

  data[0] = new byte[] { 10, 20, 30, 40, 50 };
  data[1] = new byte[] { 11, 21, 31, 41, 51, 61, 71, 71, 81, 92 };
  data[2] = new byte[] { 12, 22, 32 };
  data[3] = new byte[] { 13, 23, 33, 43, 53, 63, 73 };

  Action print = () =>
  {
    foreach ( var row in data )
    {
      Console.Write("  ");
      foreach ( var item in row )
        Console.Write(item + " ");
      Console.WriteLine();
    }
  };

  Console.WriteLine("Jagged array before save:");
  print();
  JaggedArrayHelper.Save(filename, data);

  data = JaggedArrayHelper.Load(filename);
  Console.WriteLine();
  Console.WriteLine("Jagged array after load:");
  print();
}

Output

Jagged array before save:
  10 20 30 40 50
  11 21 31 41 51 61 71 71 81 92
  12 22 32
  13 23 33 43 53 63 73

Jagged array after load:
  10 20 30 40 50
  11 21 31 41 51 61 71 71 81 92
  12 22 32
  13 23 33 43 53 63 73

Future improvements

We can add some fields to define a header to help to recognize file description and type like JaggedBytesArray.

We can also manage the case of data readed does not match the intended count and show a message or raise an exception in addition of breaking the loop.

-1

This does what you want, by writing each row of the image data in turn to the output file:

byte[][] imgdata = image.ImageByteArrayList;
using (FileStream file = new FileStream(FileNameLocation, FileMode.Create, System.IO.FileAccess.Write))
{
    for (int i = 0;  i < imgdata.Length;  i++)
        file.Write(imgdata[i], 0, imgdata[i].Length);   // Write a row of bytes
    file.Flush();
    file.Close();
    file.Dispose();
}

This has the advantage of using the image array in place, without the need to convert it into a different one-dimensional array (which could be quite expensive).

David R Tribble
  • 11,918
  • 5
  • 42
  • 52