Witam. Piszę swoją małą obsługę zapisu i odczytu rekordów z pliku. Z góry proszę o nie polecanie mi gotowych baz typu SQLight itp ;) . Chce mieć coś małego i szybkiego dla własnych drobnych potrzeb. I tak, procedury prawdopodobnie działają tylko niektóre osoby zgłaszają mi błąd odczytu bazy. Ja nigdy takiej sytuacji nie miałem, ale to chyba dlatego że nie używałem własnego kreatora starej bazy na nową ;) Jestem przekonany że coś skopałem w kreatorze ale chciałbym aby jakiś spec obejrzał procedurki odczytu i zapisu (zwłaszcza to czy można wczytywać niepełną wielkość rekordu - wyjaśnione w kodzie). Mam standardowy rekord który ma w sobie pola o stałej długości jak i jedno o nieograniczonej. Rozwiązałem to tak że mam jedno pole pomocnicze które pamięta ilość znaków pola o nieograniczonej wielkości. Wskaźniki do rekordów trzymam w TList.
Kod:
type
TBaza = packed record
Imie: String[25];
Nazwisko: string[25];
Wiek: Byte;
DlugoscNotki: Integer;
Notka: String;
end;
//zapis
procedure ZapisBazy;
var
S: TFileStream;
i, PakietSize: Integer;
tmpRec: PBaza;
tmNotka: String;
begin
S := TFileStream.Create(PathBaza, fmCreate);
try
try
//faktyczna wielkosc rekordu do zapisu (bez wielkosci zmiennej String)
PakietSize := SizeOf(TBaza)-SizeOf(String);
//petla po rekordach i zapis do pliku
for i:=0 to Pred(ListaTList.Count) do
begin
tmpRec := ListaTList.Items[i];
//zapamietuje wielkosc notki aby przy odczycie wiedziec ile bajtow pobrac
tmpRec^.DlugoscNotki := Length(tmpRec^.Notka);
//rekord
S.WriteBuffer(tmpRec^, PakietSize);
//notka
tmNotka := tmpRec^.Notka;
S.Write(tmNotka[1], tmpRec^.DlugoscNotki);
end;
except
InfoMsg('Błąd podczas zapisu bazy danych', NAZWAFULL, MB_OK or MB_ICONERROR);
end;
finally
S.Free;
end;
end;
//odczyt
procedure OdczytBazy;
var
S: TFileStream;
tmpRec: PBaza;
PakietSize: Integer;
tmpNotka: String;
begin
//jak nie ma pliku bazy to wychodze
if not FileExists(PathBaza) then Exit;
S := TFileStream.Create(PathBaza, fmOpenReadWrite or fmShareDenyWrite);
try
//faktyczna wielkosc rekordu do odczytu (bez wielkosci zmiennej String)
PakietSize := SizeOf(TBaza)-SizeOf(String);
//petla w pliku i odczyt rekordow
try
while S.Position<S.Size do
begin
New(tmpRec);
//odczyt rekordu
S.ReadBuffer(tmpRec^, PakietSize);
//odczyt ostatniej notki
SetLength(tmpNotka, tmpRec^.DlugoscNotki);
S.ReadBuffer(tmpNotka[1], tmpRec^.DlugoscNotki);
tmpRec^.Notka := tmpNotka;
SetLength(tmpNotka, 0);
//dodaje do listy
ListaTList.Add(tmpRec);
end;
//sortuje liste
ListaTList.Sort(@Posortuj);
except
InfoMsg('Błąd podczas odczytu bazy danych', NAZWAFULL, MB_OK or MB_ICONERROR);
end;
finally
S.Free;
end;
end;