使用C#读取/写入包含可变大小2D数组的结构

时间:2018-07-31 23:05:15

标签: c# dynamic struct binaryfiles

我正在用C#重写一些VB代码,并且在二进制写/读操作上有点挣扎。我有一个结构(相当于VB UDT),其中包含一个标头和一个可变大小的2D数组。行数和列数存储在标题中。

可能我应该使用一个对象而不是一个结构,但是我认为这是一个不同的讨论,除非这是一个非常糟糕的主意,否则我现在宁愿坚持使用该结构。

我已经多次使用VB进行这种操作,并且只需几行代码即可完成。我通常会做的就是这样……

写: 1)使用Put语句将UDT转储到二进制文件中。

阅读: 1)使用Get语句从文件头获取行数和列数 2)使用上面找到的列/行计数来使UDT变暗并调整数组部分的大小 3)使用Get语句将文件内容读入变量

我的C#版本当前是这样的:

Type

GridStruct是包含标头和2D数据数组的结构。它的相关部分如下所示:

using (BinaryReader b = new BinaryReader(File.Open( [filename] ,FileMode.Open)))
{

  // Read number of rows and columns...
  byte[] buff = b.ReadBytes(Marshal.SizeOf(typeof(GridStructHeader))); // read byte array
  GCHandle handle = GCHandle.Alloc(buff, GCHandleType.Pinned); // protect buffer from GC
  //Marshal the bytes...
  GridStructHeader h = 
    (GridStructHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), 
    typeof(GridStructHeader));
  handle.Free(); // give control of the buffer back to the GC 

  // Create structure...
  GridStruct grd = new GridStruct();
  grd.Cell = new GridCell[h.NumCols, h.NumRows];

  // Read grid into memory...
  buff = b.ReadBytes(Marshal.SizeOf(grd)); // size buffer to match structure
  handle = GCHandle.Alloc(buff, GCHandleType.Pinned);
  grd = (GridStruct)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), 
    typeof(GridStruct));
  handle.Free();

}

GridStructHeader是一种数据类型,为方便起见,仅包含标题的第一部分。我将其用作读取行数和列数(均为Int数据类型)的一种方式。最初,我尝试使用ReadInt32()来分别读取值,但这没有用,我将其归类为序列化。

GridStructHeader包含行数和列数(以及一些其他字段,为简单起见,在此省略)

[Serializable]
struct GridStruct
{
  public int NumCols;
  public int NumRows;
  public GridCell[,] Cell;
}

GridCell是一个结构,其中包含网格(AKA矩阵AKA 2D数组)中每个单元格的内容。

运行上面的命令时,我在行中收到一个AccessViolation异常

[Serializable]
struct GridStructHeader
{
  public int NumCols;
  public int NumRows;
}

我认为我的方法不太正确。如果有人可以建议如何最好地做到这一点,将不胜感激。不必特别快。代码的清晰度和简洁性更高。

0 个答案:

没有答案