gpt4 book ai didi

c# - 读取包含未知数量结构的二进制文件 (C#)

转载 作者:太空宇宙 更新时间:2023-11-03 22:19:58 25 4
gpt4 key购买 nike

好的,所以我目前有一个包含未知数量结构的二进制文件,如下所示:

private struct sTestStruct
{
public int numberOne;
public int numberTwo;
public int[] numbers; // This is ALWAYS 128 ints long.
public bool trueFalse;
}

到目前为止,我使用以下命令将所有结构读入列表<>:

List<sTestStruct> structList = new List<sTestStruct>();

while (binReader.BaseStream.Position < binReader.BaseStream.Length)
{
sTestStruct temp = new sTestStruct();
temp.numberOne = binReader.ReadInt32();
temp.numberTwo = binReader.ReadInt32();
temp.numbers = new int[128];
for (int i = 0; i < temp.numbers.Length; i++)
{
temp.numbers[i] = binReader.ReadInt32();
}
temp.trueFalse = binReader.ReadBoolean();

// Add to List<>
structList.Add(temp);
}

我真的不想这样做,因为一次只能向用户显示一个结构,所以一次读取多个记录没有意义。所以我认为我可以使用类似的方法读取特定记录:

fileStream.Seek(sizeof(sTestStruct) * index, SeekOrigin.Begin);

但它不会让我知道 sTestStruct 的大小,结构不会让我预定义数组大小,那么我该怎么做呢??

最佳答案

sTestStruct 不存储在一个连续的内存区域中,sizeof(sT​​estStruct) 与文件中记录的大小没有直接关系。 numbers 成员是对您在阅读代码中自行分配的数组的引用。

但是您可以轻松地在代码中指定记录大小,因为它是一个常量值。此代码将查找位于 index 的记录。然后,您可以使用循环主体读取一条记录。

const Int32 RecordSize = (2 + 128)*sizeof(Int32) + sizeof(Boolean);
fileStream.Seek(RecordSize * index, SeekOrigin.Begin);

如果您有许多不同的固定大小的记录,并且担心手动输入每条记录的记录大小容易出错,您可以设计一个基于反射和自定义属性的方案。

创建一个属性来定义数组的大小:

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
sealed class ArraySizeAttribute : Attribute {

public ArraySizeAttribute(Int32 length) {
Length = length;
}

public Int32 Length { get; private set; }

}

在记录类型上使用属性:

private struct sTestStruct {   
public int numberOne;
public int numberTwo;
[ArraySize(128)]
public int[] numbers; // This is ALWAYS 128 ints long.
public bool trueFalse;
}

然后您可以使用此示例代码计算记录的大小:

Int32 GetRecordSize(Type recordType) {
return recordType.GetFields().Select(fieldInfo => GetFieldSize(fieldInfo)).Sum();
}

Int32 GetFieldSize(FieldInfo fieldInfo) {
if (fieldInfo.FieldType.IsArray) {
// The size of an array is the size of the array elements multiplied by the
// length of the array.
var arraySizeAttribute = (ArraySizeAttribute) Attribute.GetCustomAttribute(fieldInfo, typeof(ArraySizeAttribute));
if (arraySizeAttribute == null)
throw new InvalidOperationException("Missing ArraySizeAttribute on array.");
return GetTypeSize(fieldInfo.FieldType.GetElementType())*arraySizeAttribute.Length;
}
else
return GetTypeSize(fieldInfo.FieldType);
}

Int32 GetTypeSize(Type type) {
if (type == typeof(Int32))
return 4;
else if (type == typeof(Boolean))
return 1;
else
throw new InvalidOperationException("Unexpected type.");
}

像这样使用它:

var recordSize = GetRecordSize(typeof(sTestStruct));
fileStream.Seek(recordSize * index, SeekOrigin.Begin);

您可能需要对此代码进行一些扩展才能在生产中使用它。

关于c# - 读取包含未知数量结构的二进制文件 (C#),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3493769/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com