Ktoś może mi dać namiary? - jakiś artukuł, przykład szczególnie jeżeli chodzi o tablice dynamiczne
dla pliku amorficznego
BlockWrite(plik,tablica,sizeof(tablica));
albo w pętli dla pliku typowanego
for i := 0 to length(tablica)-1 do write(f,tablica[i]);
analogicznie z odczytem.
do czegoś tak prostego ma być artykuł?
Wszystko co się wie jest proste...dzięki, zapomniałem o plikach niezdefiniowanych :)
dla pliku amorficznego
BlockWrite(plik,tablica,sizeof(tablica));
eee ? dla tablicy dynamicznej to będzie raczej:
BlockWrite(plik,tablica[0],length(tablica));
eee ? dla tablicy dynamicznej to będzie raczej:
BlockWrite(plik,tablica[0],length(tablica));
szczególnie, jak zapisujesz do pliku nietypowanego. wtedy zapiszesz tyle bajtów, ile elementów ma tablica, a to przeważnie za mało ;-)
poza tym adres tablica i tablica[0] jest taki sam, bo tablica zaczyna się od zerowego elementu...
Szanowny ŁK to nie działa...(bez komentarzy)
Dajcie trochę wzkazówek albo jakieś namiary. To jest rzeczywiście takie proste, że szkoda gadać (opinia ŁK)?
Jak Piechnat poradził - działa tylko nie wiem co z Rewrite i Reset jak dam Rewrite(plik) to nie działa, jak dam Rewrite(plik,1), to zapisze i odczyta tylko pokaże Runtime error 204, jak dam Rewrite(plik, SizeOf(tablica)) to sie wiesza.
W moim programie sprawa nie będzie chyba prosta. Mam trochę skompikowane struktury - recordy składające się m. in. z dynamicznych tablic recordów itd. To mi wszystko działa tylko muszę to zapisywać (kurde może trzeba bylo od tego zacząć?). Jak to zapisywać?
// ŁF!!!!!!
No cóż, pomyłki chodzą po ludziach, a mi w D5 to też nie bardzo działa. Działa natomiast takie coś :
type
TRekord = record
zm1 : byte;
zm2 : string[20];
end;
var
tablica : array of TRekord;
F : file of TRekord;
begin
SetLength(tablica, 3);
AssignFile(F, 'd:\\plik.rec');
Rewrite(F);
BlockWrite(F, tablica[0], Length(tablica));
CloseFile(F);
end;
//DOPISANE
i ŁF a nie ŁK
lub var f:file; //... rewrite(f,1); BlockWrite(F, pointer(tablica)^, Length(tablica)*sizeof(trecord)); pointer(tablica)^ da ten sam efekt co tablica[0], a </u>Length(tablica)*sizeof(trecord)</u> jest chyba oczywiste ;] [mf]
Tą sytuację rozumiem, tylko co zrobić kiedy jedno z pól rekordu jest tablicą dynamiczną?
Tą sytuację rozumiem, tylko co zrobić kiedy jedno z pól rekordu jest tablicą dynamiczną?
To masz problem, mozesz to zapisac do nietypowanego, ale potem tego nie odczytasz, musialbys wymysles jakis wlasny format, najpierw jakis naglowek, w nim zapisane informacje o wielkosci danych, po jego odczytaniu wiesz jaka dlugosc ma tablica i ja czytasz.
Dzięki :) ..."ja wiedziałem że tak będzie"...
Ale jak ktoś robił coś takiego, to niech wrzuci przykład, jak ja to zrobię, to dam znać
Wystarczy troche poglowkowac:
Prosty przyklad z zapisywaniem kilku tablic dynamicznych w jednym pliku, nie wiem czy nie ma bledow, bo mam kopniete delphi i nic nie chce sie instalowac, ale glownie chodzi o idee:
zapisywanie
procedure TForm1.Button1Click(Sender: TObject);
type
MyString = String[50];
THeader = record
Name: String[10];
Length: Integer;
end;
var
tablica : array of MyString;
Header: THeader;
F : file;
begin
AssignFile(F, 'd:\\plik.rec');
Rewrite(F); //standard
//Robimy se 1 tablice
SetLength(tablica, 3);
tablica[0] := 'jakis ciag w 1 tablicy';
tablica[1] := 'ciag 2 w 1 tablicy';
tablica[2] := 'ciag 3 w 1 tablicy';
//zapisujemy
Header.Name := 'tablica 1';
Header.Length := Length(tablica);
BlockWrite(F, Header, SizeOf(Header));
BlockWrite(F, tablica[0], Length(tablica) * SizeOf(MyString));
//Robimy se 2 tablice
SetLength(tablica, 2);
tablica[0] := 'jakis ciag w 2 tablicy';
tablica[1] := 'ciag 2 w 2 tablicy';
//zapisujemy
Header.Name := 'tablica 2';
Header.Length := Length(tablica);
BlockWrite(F, Header, SizeOf(Header));
BlockWrite(F, tablica[0], Length(tablica) * SizeOf(MyString));
CloseFile(F);
end;
odczytywanie
procedure TForm1.Button2Click(Sender: TObject);
type
MyString = String[50];
THeader = record
Name: String[10];
Length: Integer;
end;
var
tablica : array of MyString;
Header: THeader;
F : file;
q: Integer;
begin
AssignFile(F, 'd:\\plik.rec');
Reset(F); //standard
BlockRead(F, Header, SizeOf(Header));
SetLength(tablica, Header.Length);
BlockRead(F, tablica[0], Length(tablica) * SizeOf(MyString));
Memo1.Lines.Add(Header.Name);
for q := Low(tablica) to High(tablica) do
Memo1.Lines.Add(tablica[q]);
CloseFile(F);
end;
// posadziłeś byki - musi być reset(f,1) i rewrite(f,1) - bo to są pliki amorficzne - ŁF
// o tym nie wiedzialem, thx.
Dzięki za cierpliwość. To pojąłem. Sprawa z zapisem tablic dynamicznych jest jasna. Header zawiera informacje o tablicach. Tylko mi chodzi o sprawę zasadniczą (która być może nie stanowi problemu tylko nie wiem jak się do tego zabrać)
Czy można zapisać w całości np. coś takiego?
Trec=record
field1:Integer;
field2:array of string[50];
end;
to JEST proste, tak jak pisałem wcześniej z małymi poprawkami (bo sizeof(a)=4, a a^ nie działa)
var
f : file;
a : array of ShortString;
i : integer;
begin
// tu zapisywanie
SetLength(a,10000);
for i := 0 to 9999 do
a[i] := inttostr(i);
assign(f,'plik');
rewrite(f,1);
blockwrite(f,a[0],sizeof(a[0])*length(a));
close(f);
// tu odczyt
setlength(a,1); // 1 potrzebne do pobrania rozmiaru elementu tablicy
assign(f,'plik');
reset(f,1);
setlength(a,filesize(f) div sizeof(a[0]));
blockread(f,a[0],sizeof(a[0])*length(a));
close(f);
end.
[dopisane]
cholera, nie zauważyłem że temat ma dwie strony....
Czy można zapisać w całości np. coś takiego?
Trec=record
field1:Integer;
field2:array of string[50];
end;
nie możesz, bo tablica dynamiczna jest tak naprawdę tylko wskaźnikiem. sizeof(trec)=8 - 4 bajty integer i 4 tablica dynamiczna. ale nie zawsze musisz zapisywać długość (patrz kod wyżej), a jak się zaprzesz, to możesz zapisywać sobie stringi do pliku tekstowego wraz z ich ilością.
Ok, wielkie dzięki nauczyliście mnie zapisywać tablice dynamiczne ale powiedzcie czy da się zapisać w całości coś takiego:
Trec=record
field1:Integer;
field2:array of string[50];
end;
Ok, wielkie dzięki nauczyliście mnie zapisywać tablice dynamiczne ale powiedzcie czy da się zapisać w całości coś takiego:
Trec=record
field1:Integer;
field2:array of string[50];
end;
Tak samo jak wczesniej, czyli odczytujesz headera, powiekszasz tablice w rekordzie i wczytujesz jego zawartosc z pliku.
Ok, tylko jak to zapisać? (tylko nie mów że odwrotnie jak odczytać)
Glowy nie dam, bo pisze ze stronki, ale bedzie to cos takiego, czyli podobne do poprzedniego. nie wiadomo jak z ta tablica (czy zadziala sizeof calego rekordu), jak nie to bedzie cie to kosztowac troche matematyki z wyliczeniem wielkosci rekordu (przy zapisaniu) i dlugosci tablicy (przy odczytywaniu)
procedure TForm1.Button1Click(Sender: TObject);
type
THeader = record
Length: Integer;
end;
TRecord = record;
cos: Integer;
tablica: array of String[20];
end;
var
rec: TRecord;
Header: THeader;
F : file;
begin
AssignFile(F, 'd:\\plik.rec');
Rewrite(F, 1);
//Tu se cos z tym rekordem robisz
//zapisujemy
Header.Length := Length(Rec.tablica);
BlockWrite(F, Header, SizeOf(Header));
BlockWrite(F, Rec, SizeOf(Rec));
CloseFile(F);
end;
procedure TForm1.Button2Click(Sender: TObject);
type
//jak wyzej
var
//jak wyzej +
q: Integer;
begin
AssignFile(F, 'd:\\plik.rec');
Reset(F, 1);
BlockRead(F, Header, SizeOf(Header));
SetLength(Rec.tablica, Header.Length);
BlockRead(F, Rec, SizeOf(Rec));
//odczytany rec
CloseFile(F);
end;
<font color="darkblue">//rozmiar mozna bardzo latwo policzyc dodajac do siebie wszystko co jest w rekordzie + dlugosc tablicy * wielkosc jej elementu, troszke trudniej z wyliczeniem dlugosci na podstawie wielkosci ale jak napisalem troszke</span>
Chyba problem sprowadza się tylko do zapisu. I chyba to co zapisałeś nie zadziała
Z pewnością nie SizeOf(rec) ponieważ ta funkcja nie da rozmiaru zmiennej tworzonej dynamicznie. Size rec można łatwo obliczyć:=mem2-mem1 gdzie m1:=AllocMemSize przed wypełnieniem recordu a m2 po jego wypełnieniu. Ale i tak nic z tego... [???]
Dzisiaj już tego nie sprawdzę muszę wstać od kompa
nie kumam - dałem Ci działające rozwiązanie, co za problem dorzucić tam jeszcze odczyt jakiegoś integera?
A co ja mam powiedzieć? Wcześniej mówisz, że się nie da tego zapisać, teraz że no problem, chyba że jest was kilku ŁK, ale wielkie dzięki myślę, że nie był to czas stracony :)
// mówiłem, że nie da się tego zapisać w takiej postaci - nie przeczytałeś uważnie - ŁF
Oj przepraszam ŁF
// zabiję, wypatroszę, ugotuję, dam psom na pożarcie i zbanuję. no i jaja urwę. ŁF
Wróciłem do tego wątku bo skończyłem testowanie plików nietypowanych w swoim programie. Wolverine i ŁF - wielkie dzięki!!!
Dla tych co jeszcze nie stosowali plików niezdefiniowanych - to jest rewelacja. Jedna uwaga. Robiąc header(informacja o zapisywanych zmiennych) zapisujcie FilePos, żeby później nie było problemów z odczytem (Seek)