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