2

I was wondering if there is any way to use System.IO.BinaryWriter in C# to write an array of template/generic type?

For example, I have a buffer in a templated struct:

T[] buffer

T is typically either bool or byte. The idea was to have methods for writing each of these types like:

public void WriteByte(System.IO.BinaryWriter writer, int sizeToWrite)
{
  if (typeof(T) != typeof(byte)) Error.Happened("Struct is not of type byte.");

  // Direct use does not work even when T is 'byte'
  writer.Write(buffer[i], 0, sizeToWrite);

  // Casting does not work
  writer.Write((byte[])buffer[i], 0, sizeToWrite);
}

However, there seems to be no way to use the templated array for writing.

Any suggestions would be very welcome!

ares_games
  • 1,019
  • 2
  • 15
  • 32

2 Answers2

2

I'm not quite sure what the purpose is but a way to go could be this:

public static void WriteByte<T>(T[] data, Converter<T, byte[]> converter, string path)
{
  using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
  {
    using (BinaryWriter writer = new BinaryWriter(stream))
    {
      foreach (var x in data)
      {
        var bytes = converter(x);
        foreach (var b in bytes)
        {
          writer.Write(b);
        }
      }
    }
  }
}

or more simple

public static void WriteBytes<T>(T[] data, Converter<T, byte[]> converter, string path)
{
  using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
  {
    foreach (T x in data)
    {
      var buffer = converter(x);
      stream.Write(buffer, 0, buffer.Length);
    }
  }
}

test case:

static void Main(string[] args)
{
  byte[] data = { 1, 2, 3, 4, 5, 6, 7 };
  WriteByte(data, (b) => new byte[] { b }, @"C:\Temp\MyBinary1.myb");

  int[] intData = { 1, 2, 3, 4, 5, 6, 7 };
  WriteByte(intData, BitConverter.GetBytes, @"C:\Temp\MyBinary2.myb");

  long[] longData = { 1, 2, 3, 4, 5, 6, 7 };
  WriteByte(longData, BitConverter.GetBytes, @"C:\Temp\MyBinary3.myb");

  char[] charData = { '1', '2', '3', '4', '5', '6', '7' };
  WriteByte(charData, BitConverter.GetBytes, @"C:\Temp\MyBinary4.myb");

  string[] stringData = { "1", "2", "3", "4", "5", "6", "7" }; 
  WriteByte(stringData, Encoding.Unicode.GetBytes, "C:\Temp\MyBinary5.myb");


}

EDIT:

Another approach could be this:

    public static void WriteBytes3<T>(T[] data, Action<T> writer)
    {
      foreach (T x in data)
      {
        writer(x);
      }
    }

    static void Main(string[] args)
    {

      using (FileStream stream = new FileStream(@"C:\Temp\MyBinary6.myb", FileMode.Create, FileAccess.Write, FileShare.None))
      using (BinaryWriter writer = new BinaryWriter(stream))
      {
        WriteBytes3(intData, writer.Write);
      }
    }
-2
for(int i = 0; i < sizeToWrite; ++i)
{
    writer.Write((byte)buffer[i]);
}

Or more efficient

writer.Write(Array.ConvertAll(buffer, b => (byte)b), 0, sizeToWrite);
airafr
  • 332
  • 2
  • 7