Najlepiej by było, gdybyś napisał sobie zestaw procedur/funkcji do obsługi swoich typowanych plików. Głównie po to, aby mieć jeden konkretny sposób obsługi (czyli użycie strumieni) i jeden, zunifikowany zestaw instrukcji. Dla przykładu, wydzielić można odczyt i zapis:
procedure FileReadRecord(AStream: TStream; out ARecord: TRecord); overload;
procedure FileReadRecord(AStream: TStream; out ARecord: TRecord; AIndex: Int64); overload;
procedure FileWriteRecord(AStream: TStream; const ARecord: TRecord); overload;
procedure FileWriteRecord(AStream: TStream; const ARecord: TRecord; AIndex: Int64); overload;
{...}
procedure FileReadRecord(AStream: TStream; out ARecord: TRecord);
begin
ARecord := Default(TRecord);
AStream.Read(ARecord, SizeOf(ARecord));
end;
procedure FileReadRecord(AStream: TStream; out ARecord: TRecord; AIndex: Int64);
begin
ARecord := Default(TRecord);
AStream.Position := AIndex * SizeOf(ARecord);
AStream.Read(ARecord, SizeOf(ARecord));
end;
procedure FileWriteRecord(AStream: TStream; const ARecord: TRecord);
begin
AStream.Write(ARecord, SizeOf(ARecord));
end;
procedure FileWriteRecord(AStream: TStream; const ARecord: TRecord; AIndex: Int64);
begin
AStream.Position := AIndex * SizeOf(ARecord);
AStream.Write(ARecord, SizeOf(ARecord));
end;
I teraz tych uniwersalnych funkcji możesz użyć np. do odczytu całego pliku (wersje dwuparametrowe), ale też do swapa rekordów (wersje z trzema parametrami). Wtedy też procedurka swapująca zmieni wygląd na poniższy:
procedure FileSwapRecords(AStream: TStream; AIndex1, AIndex2: Int64);
var
LRecord1, LRecord2: TRecord;
begin
LRecord1 := Default(TRecord);
LRecord2 := Default(TRecord);
FileReadRecord(AStream, LRecord1, AIndex1);
FileReadRecord(AStream, LRecord2, AIndex2);
FileWriteRecord(AStream, LRecord1, AIndex2);
FileWriteRecord(AStream, LRecord2, AIndex1);
end;
A jeszcze lepiej by było napisać swoją klasę do obsługi tych konkretnych plików, dziedzicząc z bazowej klasy TStream
, nadpisując metody takie jak Read
i Write
oraz definiując własne. Wtedy zamiast użerać się z osobnym obiektem strumienia i globalnymi procedurami, można by ładnie operować na czytelnych metodach jednego obiektu.