| Autor | Správa |
Siriuse
 Užívateľ
 Založený: 23.05.2009 Príspevky: 81 Bydlisko: Michalovce
 | Zaslal: So 30.05.09 17:08 |   |
Viem ze existuju klasice procedury na ukladanie na disk ako StringList.SaveToFile a LoadFromFile ale ja mam StringList ako sucast vacsej struktury uvadzam priklad
| kód: |
ttabulka = record
Stlpec1:TStringlist;
Stlpec2:TStringLIst;
Stlpec3:TStringList;
end;
Tstruktura = record
nieco:String;
nieco:string;
tabulka:Ttabulka;
end;
var
subor:File of Tstruktura;
|
Aj ked je nieco zadane v stringlistoch, a je to som si overil neulozi na disk nic. Preco? Mam na to pouzit streamy? ak hej tak ako? |
| |
   |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 1052
 | Zaslal: So 30.05.09 19:01 |   |
Nezapíše sa ti nič, pretože:
1.) do súboru ukladáš celú štruktúru TStruktura a do súboru sa nedá zapísať dátový typ TStringList.
2.) do súboru môžeš ukladať premenné, ktorých veľkosť v pamäti je daná už v dobe vívoja (takže taký string nepôjde, alebo ak, tak maximálne iba 255 znakov).
Teda ak nehodláš využívať zapuzdrené funkcie SaveToFile a LoadFromFile, tak na tvojom mieste by som použil stream-y:
| kód: | TTabulka = record
Stlpec1: TStringList;
Stlpec2: TStringLIst;
Stlpec3: TStringList;
end;
TStruktura = record
nieco: string;
nieco2: string;
tabulka: Ttabulka;
end;
var
s: TStream;
struktura: TStruktura;
...
procedure Zapis();
begin
s:= TFileStream.Create('subor.txt', fmCreate);
s.WriteBuffer(struktura.nieco[1], Length(struktura.nieco));
s.WriteBuffer(struktura.nieco2[1], Length(struktura.nieco2));
struktura.tabulka.Stlpec1.SaveToStream(s);
struktura.tabulka.Stlpec2.SaveToStream(s);
struktura.tabulka.Stlpec3.SaveToStream(s);
s.Free;
end; |
|
| |
   |
 |
Siriuse
 Užívateľ
 Založený: 23.05.2009 Príspevky: 81 Bydlisko: Michalovce
 | Zaslal: So 30.05.09 20:26 |   |
a neda sa kombinovat typovy subor s Streamom tak ze
| kód: |
Tstruktura = record
nieco:string;
nieco:string;
tabulka: TStream;
end;
var
struktura:Tstruktura;
procedure ulozclick(sender:Tobject);
var
subor: File of Tstruktura;
begin
assignfile(Filepath, subor);
rewrite(subor);
struktura.nieco:='nieco';
struktura.tabulka:=TFileStream.create(a tu co?);
struktura.tabulka.savetostream(stlpec1);
write(subor,struktura);
struktura.tabulka.free;
closefile(subor);
end;
|
Ci musim pouzit iba hole streami, pretoze takto cez binarne typove subory je pohodlne nacitavat ostatne premenne, teda okrem tabulky. A ak nie tak potom citaju zo streamov tie stlpce? |
| |
   |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 1052
 | Zaslal: Ne 31.05.09 10:37 |   |
Nemôžeš to takto kombinovať, lebo opäť zapisuješ do súboru dátový typ, ktorý nie je možné zapísať (zapísať sa dá, ale nebude to nič "čítatelné").
Keď budeš spätne čítať zo súboru pomocou stream-ov, budeš potrebovať vedieť, koľko znakov máš načítať, pretože inak by ti načítalo najväčší možný počet znakov. Takže preto keď budeš zapisovať do súboru pomocou stream-u reťazce, predtým ešte daj do súboru zapísať číselnú hodnotu, ktorá bude predstavovať počet znakov, ktoré hodláš zapísať. |
| |
   |
 |
Siriuse
 Užívateľ
 Založený: 23.05.2009 Príspevky: 81 Bydlisko: Michalovce
 | Zaslal: Ne 31.05.09 11:25 |   |
a dlzku StringListov netreba zadavat? |
| |
   |
 |
Siriuse
 Užívateľ
 Založený: 23.05.2009 Príspevky: 81 Bydlisko: Michalovce
 | Zaslal: Ne 31.05.09 15:16 |   |
napises mi ako sa to nacitava?? lebo systemom subor.loadfromstream(stream); nejde |
| |
   |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 1052
 |
Treba aj dĺžku StringListov, aby si vedel, koľko znakov patrí do tohto listu. Reťazce potom načítavaš takto (ak si ich predtým uložil štýlom dlžka-reťazec):
| kód: | s:= TFileStream.Create('E:\subor.txt', fmOpenRead);
s.ReadBuffer(dlzka, sizeOf(integer));
s.ReadBuffer(struktura.nieco[1], dlzka);
s.ReadBuffer(dlzka, sizeOf(integer));
struktura.tabulka.Stlpec1.LoadFromStream(s); |
Problém ale nastane pri načítavaní StringListov. Keď ich máš v stream-e viac, tak to robí problémy a načíta okrem textu aj uloženú veľkosť nasledujúceho stream-u a teda pri čítaní ďalšieho integera nastane chyba. S týmto ti fakt neviem pomôcť, nikdy som nerobil takéto zložité načítavania zo stream-u. Nech sa skúsi ozvať niekto iný.
// keby bolo na mne, tak ja by som asi načítaval text do StringListov po jednotlivých znakoch, pričom počet znakov by som vedel podľa načítanej veľkosti StringListu |
| |
   |
 |
Siriuse
 Užívateľ
 Založený: 23.05.2009 Príspevky: 81 Bydlisko: Michalovce
 | Zaslal: Po 01.06.09 13:19 |   |
No tak... ako by si to riesil. Zadanie.
Tabulka do ktorej sa zadavaju udaje. Ma 9 stlpcov, pocet stlpcov sa nemeni. Pocet riadkov je vysoky, moze byt rozny (aj 300 alebo aj 1200). Po kazdom pridani riadku, je tam udalost rovno v komponente, onInputAdded, to neje problem. Pri stlaceni F2 sa ti na ulozit do suboru spolu s inymi datami (nejakym zaznamom) na disk. AKO TO SPRAVIT? |
| |
   |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 1052
 | Zaslal: Po 01.06.09 13:43 |   |
Tak ja by som uložil celú tabuľku do jedného StringListu a to tak, že by som pomocou cyklu for i:= 1 to pocetriadkov do začal v prvom riadku a zapísal z neho všetky stĺpce, potom do druhého, atď. Takto by bola celá tabuľka v jednom StringListe, ktorého obsah by som uložil do stream-u spolu s inými dátami a to takto:
| kód: | procedure Zapis();
begin
s:= TFileStream.Create('subor.txt', fmCreate);
dlzka:= Length(struktura.nieco);
s.WriteBuffer(dlzka, sizeOf(integer));
s.WriteBuffer(struktura.nieco[1], Length(struktura.nieco));
dlzka:= Length(struktura.nieco2);
s.WriteBuffer(dlzka, sizeOf(integer));
s.WriteBuffer(struktura.nieco2[1], Length(struktura.nieco2));
struktura.CelaTabulka.SaveToStream(s);
s.Free;
end; |
A potom spätne načítal takto:
| kód: | procedure Citaj();
begin
s:= TFileStream.Create('E:\subor.txt', fmOpenRead);
s.ReadBuffer(dlzka, sizeOf(integer));
s.ReadBuffer(struktura.nieco[1], dlzka);
s.ReadBuffer(dlzka, sizeOf(integer));
s.ReadBuffer(struktura.nieco2[1], dlzka);
struktura.CelaTabulka.LoadFromStream(s);
s.Free;
end; |
|
| |
   |
 |
|