Generalnie do tego typu danych świetnie nadają się rekordy
TDane=packed record
kNick:ShortString;
kId : ShortString;
kDate : TDateTime;
kClicked : Boolean;
end;
Potem pracujesz z file of TDane i polecaniami Write, Read, BlockWrite i BlockRead. BlockWrite i BlockRead są bardzo dobre, gdy trzymasz dane w tablicy array of TDane - można szybko czytać i pisac dane. Trzymając dane w ListBoxie musisz raczej zapisywać w pętli Write'm albo czytac Readem. Albo tak jak ja zrobiłem w pewnym programie - dane oryginalne były trzymane w array of TPewienTyp i szybko pisane lub czytane z dysku, a kiedy trzeba wyswietlane w ListView (z uzyciem BeginUpdate i EndUpdate zeby bylo szybciej).
Jest jednak pewien problem, który pewnie zauważyłeś. Zmieniłem kNick na shortstring. Zwykły string nie może bowiem występować w rekordzie zapisywanym do dysku, bo 1. jest wskaźnikiem i 2. nieznana jest z góry długość danych. Jeśli musisz używać zwykłego (długiego stringu) to albo uzyj zwykłych plików tekstowych (ew. ini), albo pliku nietypowanego (lub file of byte) i czytaj tak (założenie że do tablicy i że kNick:string)
a: array of TDane;
f: file of byte;
nicklen: longint;
w pętli i po uprzednim ustawieniu dlugosci a na calkowita dlugosc tablicy zapisaną na początku pliku [dygresja: piekno file of TDane czyli rozwiązania z shortstring polega m.in. na tym, że nie musisz zapisywac tej długości - jest ona równa FileSize(F) dla F:file of TDane]
BlockRead(F,nicklen,SizeOf(LongInt)); //odczyt wczesniej zapisanej dlugosci lancucha)
SetLength(a[i].kNick,nicklen);
BlockRead(F,a[i].kNick[1],nicklen);//odczyt dlugiego lancucha
BlockRead(F,a[i].kId,SizeOf(ShortString);
BlockRead(F,a[i].kDate,SizeOf(TDateTime));
BlockRead(F,a[i].kClicked,SizeOf(Boolean));
lub coś w tym guście - zapisujesz podobnie