Cum se salvează într-un fișier și se încarcă dintr-un fișier o matrice fără dimensiuni

Cum se salvează într-un fișier și se încarcă dintr-un fișier o matrice fără dimensiuni

Subiectul.
La încărcare, dimensiunea matricei este necunoscută. Cum să salvați un tabel într-un fișier împreună cu informațiile despre dimensiune și apoi să îl încărcați de acolo, astfel încât dimensiunea matricei să fie setată așa cum a fost atunci când ați salvat?







salvați mai întâi dimensiunea, apoi matricea însăși.

dar, în general, experiența de scriere / citire la / din fișierul (fișierele) aveți?

> la un fișier împreună cu informații despre dimensiune

și anume de exemplu, pentru a crea un FileStream, mai întâi scrie dimensiunea
Lungime (Array), SizeOf (Integer)), apoi matricea în sine, fie prin elemente, fie simultan întregul bloc

cu excepția cazului în care nu puteți citi elemente de informații despre dimensiunile matricei într-o variabilă.
și apoi, înainte de a stoca datele reale ale matricei, scrieți valorile acestor variabile în fișier.
astfel încât atunci când citiți dintr-un fișier, setați în mod corespunzător dimensiunile matricei, înainte de a citi datele din fișier în matrice.

există, de asemenea, f-tsia TVarData, VarArrayDimCount (), VarArrayLow / HighBound (), etc.
acestea vă vor permite să obțineți informații despre structura matricei pentru a păstra / citi-o că ați putea restaura structura matricei reconstruite cu un apel banal VarArrayCreate ()

În stat. Dar m-am gândit că există o cale mai ușoară și am crezut că, din moment ce cred că se va face într-un Lamer.

Totuși, au decis să încerce separat să nu salveze într-un fișier o variabilă cu un număr. înregistrări. Am scris aici, dar nu funcționează. Nu înțeleg ce se întâmplă.


tip
InfoNode = înregistrare
părinte: întreg;
fileNum: cardinal;
text: șir [120];
se încheie;
.

NodeList: matrice de InfoNode;
.

// Salvați lista de noduri într-o matrice și apoi într-un fișier
procedura TForm1.NodeSave;
var
f: fișier;
i, k: întreg;
începe
k: = TreeView1.Items.Count;
SetLength (nodelist, k); // în exemplu, numărul de noduri este 11
pentru i: = 0 până la k-1
începe
cu Treeview1.items.Item [i]
începe
dacă părinte = nul atunci nodelist [i]. Parent: = 99999999 altceva
nodelist [i] .parent: = parent.absoluteindex;
nodelist [i] .text: = text;
nodelist [i] .fileNum: = cardinal (date);
se încheie;
se încheie;
RichEdit1.lines.add (inttostr (dimensiunea (nodelist))); // Aici vedem 4
RichEdit1.lines.add (inttostr (TreeView1.items.count)); // deși aici 11

assignfile (f, "nodelist.dat");
rescrie (f, 128);
blocaj (f, nodelist, k);
fișierul closet (f);
se încheie;

// Încărcați din fișier
procedura TForm1.NodeLoad;
var
f: fișier;
începe
assignfile (f, "nodelist.dat");
resetați (f, 128);
SetLength (nodelist, FileSize (f));
blockread (f, nodelist, mărimea fișierului (f));
RichEdit1.lines.add (inttostr (dimensiunea fișierului (f))); // Aici vedem 11
fișierul closet (f);
RichEdit1.lines.add (nodelist [2] .text); // Și aici este gol, deși la nod în text a fost ceva.
se încheie;

Totuși, au decis să încerce separat să nu salveze într-un fișier o variabilă cu un număr. înregistrări. Am scris aici, dar nu funcționează. Nu înțeleg ce se întâmplă.


tip
InfoNode = înregistrare
părinte: întreg;
fileNum: cardinal;
text: șir [120];
se încheie;
.

NodeList: matrice de InfoNode;
.

// Salvați lista de noduri într-o matrice și apoi într-un fișier
procedura TForm1.NodeSave;
var
f: fișier;
i, k: întreg;
începe
k: = TreeView1.Items.Count;
SetLength (nodelist, k); // în exemplu, numărul de noduri este 11
pentru i: = 0 până la k-1
începe
cu Treeview1.items.Item [i]
începe
dacă părinte = nul atunci nodelist [i]. Parent: = 99999999 altceva
nodelist [i] .parent: = parent.absoluteindex;
nodelist [i] .text: = text;
nodelist [i] .fileNum: = cardinal (date);






se încheie;
se încheie;
RichEdit1.lines.add (inttostr (dimensiunea (nodelist))); // Aici vedem 4
RichEdit1.lines.add (inttostr (TreeView1.items.count)); // deși aici 11

assignfile (f, "nodelist.dat");
rescrie (f, 128);
blocaj (f, nodelist, k);
fișierul closet (f);
se încheie;

// Încărcați din fișier
procedura TForm1.NodeLoad;
var
f: fișier;
începe
assignfile (f, "nodelist.dat");
resetați (f, 128);
SetLength (nodelist, FileSize (f));
blockread (f, nodelist, mărimea fișierului (f));
RichEdit1.lines.add (inttostr (dimensiunea fișierului (f))); // Aici vedem 11
fișierul closet (f);
RichEdit1.lines.add (nodelist [2] .text); // Și aici este gol, deși la nod în text a fost ceva.
se încheie;

RichEdit1.lines.add (inttostr (dimensiunea (nodelist))); // Aici vedem 4

Înțelegeți de ce și multe vor deveni clare.

Propun să luați orice listă sau memo. și apoi salvați datele în acest fel Memo1.Lines.SaveToFile ("1.txt"); Și încărcați Memo1.Lines.LoadFromFile ("1.txt"); Apoi, te uiți la numărul de linii din Memo - Memo1.Lines.Count (AFIȚI ȘI LUNGIMEA MASSIVELOR). Aproape întotdeauna fac asta când trebuie să creez dinamic o matrice sau lungimea lui este necunoscută.

Deci, de fapt, eu în acest scop, de asemenea, întrebați-vă ajutorul.

citiți că există SizeOf

Lungime (nodelistă) - lungimea matricei (11)
Lungime (nodelist) * sizeof (InfoNode) - dimensiunea matricei

astfel încât, după toate, să pot rescrie totul folosind citire, citire, scriere, scriere și lucrul cu un fișier text.
Dar IMHO am probleme cu faptul că matricea este dinamică, și cu astfel de matrice nu am încercat să lucrez înainte. Și pentru a scrie ceva de tip NodeList: array [0..10000] de InfoNode; unde să declare o matrice cu un număr. elemente, care cu siguranță vor depăși valoarea cerută, într-un fel nu-mi place.
În plus, vreau să știu că încă nu sunt aici "namutil".

TFileStream, TWriter + TWriter.WriteListBegin + TWriter.WriteListEnd + metode pentru scrierea diferitelor tipuri de date pentru TWriter
+ iterație pe o matrice

Apoi, creați Memo sau Listă de liste prea dinamic și inserați și ștergeți cât va mai potrivi. Va funcționa această abordare?

assignfile (f, "nodelist.dat");
rescrie (f);
blockwrite (f, nodelist [0], lungime (nodelist) * sizeof (InfoNode));
fișierul closet (f);

assignfile (f, "nodelist.dat");
SetLength (nodelist, FileSize (f) div sizeof (InfoNode));
blockread (f, nodelist [0], mărimea fișierului (f));
fișierul closet (f);

assignfile (f, "nodelist.dat");
resetați (f);
SetLength (nodelist, FileSize (f) div sizeof (InfoNode));
blockread (f, nodelist [0], mărimea fișierului (f));
fișierul closet (f);


> Vă sugerez să luați orice listă sau memo, și apoi
> salvați datele în acest fel Memo1.Lines.SaveToFile ("1.txt");
> Și încărcați Memo1.Lines.LoadFromFile ("1.txt"); Atunci arăți
> numărul de rânduri din Memo - Memo1.Lines.Count (Aici sunteți și lungimea
> MASSIVE). Aproape întotdeauna fac asta când am o matrice
> ar trebui să fie creat dinamic sau lungimea sa este necunoscută

Poate Tstrings ar fi mai convenabil :)
Și nu am încercat :)

procedura ReadFile;
var Data: matrice de Trecord;
f: fișierul TRecord;
s: șir;
i, n: întreg;
începe
s: = "d: \ Data.dat";
AtribuițiFile (F, S);
Rewrite (f);
i: = FileSize (f); // lungimea matricei;
n: = 0;
SetLength (date, i);
În timp ce nu Eof (f) face
începe
Citiți (f, Date [n]);
inc (n);
se încheie;
CloseFile (f);
//.
//.
SetLength (date, 0);
se încheie;

procedura SaveFile;
var Data: matrice de Trecord;
f: fișierul TRecord;
s: șir;
i, n: întreg;
începe
s: = "d: \ Data.dat";
AtribuițiFile (F, S);
Resetați (f);
pentru i: = scăzut (date) la mare (date) nu scrie (f, date [i]);
CloseFile (f); // Asta e tot :)
se încheie;

Mulțumesc. Am înțeles. Deși, din anumite motive, când am introdus codul dvs., eroarea a ieșit.
Rescrieți-l astfel:

tip
InfoNode = înregistrare
părinte: întreg;
fileNum: cardinal;
text: șir [116]; // Scăzut la 116 până la sizeof (infonode) = 128
se încheie;

// Scrieți
assignfile (f, "nodelist.dat");
rescrie (f, 128);
blockwrite (f, nodelist [0], lungime (NodeList));
fișierul closet (f);

// Citirea
assignfile (f, "nodelist.dat");
resetați (f, 128);
SetLength (nodelist, FileSize (f));
blockread (f, nodelist [0], mărimea fișierului (f));
fișierul closet (f);

Prin intermediul algoritmului meu, însă, șirul [255]

assignfile (f, "nodelist.dat");
rescrie (f, 1);
blockwrite (f, nodelist [0], lungime (nodelist) * sizeof (InfoNode));
fișierul closet (f);

assignfile (f, "nodelist.dat");
resetați (f, 1);
SetLength (nodelist, FileSize (f) div sizeof (InfoNode));
blockread (f, nodelist [0], mărimea fișierului (f));
fișierul closet (f);

tip
InfoNode = înregistrare
părinte: întreg;
fileNum: cardinal;
text: șir [116]; // Scăzut la 116 până la sizeof (infonode) = 128
se încheie;

Deși există o întrebare. Se pare că întregul și cardinalul ocupă 4 octeți, total 4 + 4 + 116 = 124 și sizeof (infonode) = 128.

numai
assignfile (f, "nodelist.dat");
rescrie (f, sizeof (InfoNode)); // -.
blockwrite (f, nodelist [0], lungime (NodeList));
fișierul closet (f);

rescrie (f, 1);
resetați (f, 1);

M da. Am uitat că valoarea implicită este 128.

Ei bine, acest lucru nu mai este o problemă.
Nu am încercat, dar cred că este posibil și așa:
resetați (f, sizeof (infonode));

Apropo dacă salvezi
blocaj (f, Pointer (Integer (nodelist [0]) - 4), lungime (NodeList) +4); atunci lungimea matricei este, de asemenea, scrisă în fișier.







Articole similare

Trimiteți-le prietenilor: