好的,所以我目前有一个二进制文件,其中包含未知数量的结构,如下所示:private struct sTestStruct{ public int numberOne; public int numberTwo; public int[] numbers; // This is ALWAYS 128 ints long. public bool trueFalse;}到目前为止,我使用以下内容将所有结构读入List :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的大小,该结构不会让我预定义数组的大小,那么我该怎么做? (adsbygoogle = window.adsbygoogle || []).push({}); 最佳答案 sTestStruct不会连续存储在一个内存中,并且sizeof(sTestStruct)与文件中记录的大小没有直接关系。 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);您可能必须对此代码进行一些扩展才能在生产中使用它。 (adsbygoogle = window.adsbygoogle || []).push({});
10-06 06:51