pliki typowane - ogólnie [nie bić]

0

Tak, wiem - widzicie topik i myślicie, że znowu ktoś się nie wyslił i czeka na podpowiedź. Korzystałem z arta Adama, szukałem na forum, ale nigdzie nie znalazłem kompletnych informacji o plikach typowanych. Mam plik, w jaki sposób zapisać do niego informacje z ListBox?

kNick : String; 
kId : ShortString;
kDate : TDateTime;
kClicked : Boolean;

oraz jak je odczytać? Naprawdę, z arta 4p mało wynika jak się po pliku przemieszczać, jak czytać i podobne. Jest ostro zamotany dla osoby kompletnie nie wiedzącej o typowanych plikach. Z gory dziekuje za jakąkolwiek odpowiedz - chocby link do jakiegos topiku. (mimo, że przejrzałem ich setki)

0

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

1 użytkowników online, w tym zalogowanych: 0, gości: 1