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);
Возможно, вам придется немного расширить этот код, чтобы использовать его в работе.