Мне нужно прочитать данные из текстового файла, в котором длина полей и длина записи фиксированы. Поля заполнены нулями или пробелами, всегда отображаются в одном и том же порядке, и каждая запись заканчивается CRLF. Файл может иметь один из трех возможных типов записей, определяемых первым символом в записи.
Пока что я создал базовый класс для всех типов записей и дочерний класс для каждого типа записей.
type
TRecordBase = class abstract
public
// Various common fields...
function ToString: string; virtual; abstract;
procedure Read(AString: string); virtual; abstract;
end;
TRecordType1 = class(TRecordBase)
public
//RecordType1 fields...
function ToString: string; override;
procedure Read(AString: string); override;
end;
TRecordType2 = class(TRecordBase)
public
//RecordType2 fields...
function ToString: string; override;
procedure Read(AString: string); override;
end;
TRecordType3 = class(TRecordBase)
public
//RecordType3 fields...
function ToString: string; override;
procedure Read(AString: string); override;
end;
Затем я просто читаю каждую строку файла как строку, определяю его тип по первому символу, создаю соответствующий экземпляр класса и вызываю Read
.
Идея состоит в том, что классы Record можно использовать как для чтения, так и для записи в строковое представление записи. Процедура Read
должна разбить строку и назначить ее для открытых полей.
У меня есть два (или три) вопроса:
- Это хороший подход для обработки файлов такого типа?
- Если так, то как будет выглядеть ваша реализация процедуры
Read
? (Я имел дело с файлами с разделителями, но это мое первое знакомство с полями фиксированной длины)
- Если нет, какой подход вы бы выбрали?
Update
Просто подумал, что заполню некоторые недостающие детали. Эти классы записей по сути являются DTO (объектами передачи данных). Поля объявлены как публичные, и единственные методы предназначены для преобразования в / из строки. Единственная проверка данных на полях - это проверка типа компилятора. Поля преобразуются в строку в необходимом порядке, используя TStringBuilder.AppendFormat
. Это гарантирует, что поля дополняются и / или усекаются до нужной длины.
Я согласился с предложением Роба использовать Copy
в сочетании с соответствующим StrTo*
для получения данных из строки. Я также определил позиции и длины полей как константы класса, т.е.
const Field1Pos = 1;
const Field1Length = 1;
const Field2Pos = 2;
const Field2Length = 5;
Констант немного легче читать, чем "магические числа" при звонках на Copy
.
Будем благодарны за любые другие предложения.