Problem z zapisaniem tablicy do pliku.

Odpowiedz Nowy wątek
2011-09-03 17:43
janusz
0
type
  TDimentions = record
    Width : Integer;
    Height: Integer;
    Left : Integer;
    Top : Integer;
  end;
  TMyRecord = packed record
    D: array of TWallDimentions;
  end;
var F: File of TMyRecord;
     L: TLvlRecord;    
     I: Integer;
begin
  SetLength(L.D, Lst1.Items.Count);
 
  for I := 0 to lst1.Items.Count - 1 do
    begin
      L.D[I].Left := TShape(FindComponent(lst1.Items[I])).Left;
      L.D[I].Top := TShape(FindComponent(lst1.Items[I])).Top;
      L.D[I].Width := TShape(FindComponent(lst1.Items[I])).Width;
      L.D[I].Height := TShape(FindComponent(lst1.Items[I])).Height;
    end;
  AssignFile(F, ExtractFilePath(Application.ExeName) + edt4.Text);
  try
    try
      Rewrite(F);
      Write(F, L);
    finally
      CloseFile(F);
    end;
  except
    ShowMessage('nie dało się');
  end;
end;

W lst1 Mam listę komponentów typu TShape. Chce je (tzn. ich wymiary) zapisać do pliku, ale bezczelnie wywala mi błąd [Error] Unit1.pas(99): Type 'TMyRecord' needs finalization - not allowed in file type. Jak temu zaradzić?

Pozostało 580 znaków

2011-09-03 17:44
janusz
0

Proszę moderatora żeby zmienił

  TMyRecord = packed record
    D: array of TWallDimentions;
  end;

na

  TMyRecord = packed record
    D: array of TDimentions;
  end;

i

var F: File of TMyRecord;
     L: TLvlRecord;

na

var F: File of TMyRecord;
     L: TMyRecord;
Załóż konto, a nie modów wołasz. - payl 2011-09-03 17:57
miał konto... stracił za głupotę... - madmike 2011-09-03 18:01
Tak z ciekawości się spytam-co trzeba zrobić,żeby stracić konto na 4p? - MasterBLB 2011-09-03 20:38
Ale poza nnn'em bo to już wiemy. - szypxx 2011-09-15 22:20

Pozostało 580 znaków

2011-09-03 17:59
0

Nie wiem czy w ogóle można zapisywać arraye bezpośrednio tak na chama, więc daj tak:

TMyRecord=TDimentions;
[...]
for i:=0 to length(l)-1 do write(f,l[i]);

poza tym, zauważ że jeśli nie uda się rewritować pliku to mimo to go będzie usiłować zamknąć co oczywiście się nie uda.

EDIT:

ale bezczelnie wywala mi błąd

Linia 99? Tylko która to?!?!


Nie pisz do mnie PM o czymś co nie dotyczy bezpośrednio mnie. | Nie rozmawiaj ze mną jeśli brak Ci kultury (wystarczy że mi brakuje) | Nie jestem zły, jestem po prostu zły.
edytowany 1x, ostatnio: payl, 2011-09-03 18:00

Pozostało 580 znaków

2011-09-03 18:04
janusz
0
var F: File of TMyRecord;
Brawo, czy zrobiłeś resztę rzeczy? Modzie, chyba trzeba działać... - payl 2011-09-03 18:07
Drugi bez sensu do moda... payl opanuj się... - madmike 2011-09-03 19:25
Coś mnie napadło, zignoruj/zbanuj mnie (niepotrzebne skreślić). :-X - payl 2011-09-03 19:34

Pozostało 580 znaków

2011-09-03 18:12
janusz
0

Jaką resztę rzeczy?

Pozostało 580 znaków

2011-09-03 20:12
1

Jeżeli wywala Type 'TMyRecord' needs finalization - not allowed in file type, to polecałbym pobawić się z funkcją SizeOf oraz BlockWrite/BlockRead
Tak, czy siak i tak będziesz musiał kiedyś ich użyć...
BTW, a błąd wywala, ponieważ podczas zapisu Write/WriteLn WSZYSTKO musi mieć z góry ustalony rozmiar.

D: array of TWallDimentions;

Wg.funkcji Write jest to tablica nieskończona, więc jej zapisanie jest niemożliwe.
Musiałbyś zrobić coś takiego:

  TMyRecord = packed record
    D: array of TWallDimentions;
    Count: Integer; //Count to ilość rekordów (Count := High(D))
  end;

I pobawić się BlockWrite/BlockRead
Poszukaj, a znajdziesz masę gotowych kodów do takiego zapisu.


edytowany 2x, ostatnio: Patryk27, 2011-09-03 20:15
Czyli tak jak myślałem, zapisanie tablicy dynamicznej jest niemożliwe, ale najprościej chyba rekordy zapisać... - payl 2011-09-03 20:21

Pozostało 580 znaków

2011-09-15 22:12
ŁF
0
Patryk27 napisał(a)

Wg.funkcji Write jest to tablica nieskończona, więc jej zapisanie jest niemożliwe.
mylisz się, z "punktu widzenia funkcji" write jest to wskaźnik i taki też wskaźnik zostanie zapisany do pliku. po odczytaniu oczywiście będzie wskazywał na stare, aktualnie już nieprawidłowe, miejsce. taki problem wystąpi z każdą tablicą dynamiczną (w tym string), obiektami i jawnie zadeklarowanymi wskaźnikami. każdy element takiej tablicy/obiektu trzeba serializować osobno.


Pokaż pozostałe 2 komentarze
:) Thx ale nie znam pascala. Interesowało mnie to ze względu na pojęcie serializacji w javie. Chociaż w javie tego chyba NIE MA (tab. dynamicznych) - szypxx 2011-09-15 22:51
Tak sobie teraz pomyślałem że zmieniają się indeksy na stosie czy czymś poprzez prawdopodobnie sortowanie? - szypxx 2011-09-15 22:58
zwiększenie rozmiaru tablicy polega na utworzeniu większej tablicy, skopiowania do niej wszystkich elementów starej i uaktualnieniu wartości wskaźnika do stringa - dlatego adres musi się zmienić. z tego powodu należy jeśli to tylko możliwe od razu ustawiać odpowiednią długość tablicy - dla przykładu zwiększanie o 1 rozmiaru tablicy od 1 do 64k to 1+2+3+..64k-1 operacji kopiowania danych, czyli dla tablicy charów około 64k*64k/2 = 2GB przesuwanych danych - ŁF 2011-09-15 22:58
Czyli moja powyższa teoria jest błędna ;) Chociaż dla mnie brzmiało to logicznie że obiekt czy coś wrzucane jest na stos i kiedy zmienia się rozmiar tab to jest stos sortowany bo najlepszy w tym przypadku porządek to wg rozmiaru. - szypxx 2011-09-15 23:00
nie rozumiem? po zmianie rozmiaru kolejność wszystkich danych jest zachowana, ale nie wiem czy odpowiadam na właściwe pytanie...? - ŁF 2011-09-15 23:40

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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