Problem z zapisem rekordu do pliku - pomocy

0

Witam *

Mam taką "wariacką" strukturę:

procedure TForm1.Button1Click(Sender: TObject);
Type
  RekordJeden = Record
    Tekst1: AnsiString;	{nie jest znana długość tekstu}
    Tekst2: AnsiString;	{nie jest znana długość tekstu}
    Ilosc: Cardinal;		{tu jest wszystko jasne}
    Tablica: Array of AnsiString;	{nie jest znana wielkość tablicy i długość poszczególnych stringów}
  End;

Type
  RekordDwa = Record
    Napis1: AnsiString;	{nie jest znana długość tekstu}
    Napis2: AnsiString;	{nie jest znana długość tekstu}
    Cena: Integer;		{tu jest wszystko jasne}
    Tabela: Array of AnsiString;	{nie jest znana wielkość tablicy i długość poszczególnych stringów}
  End;

Type
  RekordCaly = Record
    Moje1: RekordJeden;
    Moje2: RekordDwa;
End;

var
 Dane: RekordCaly;

begin

 Dane.Moje1.Tekst1:='TekstPierwszy';
 Dane.Moje1.Tekst2:='TekstDrugi';
 Dane.Moje1.Ilosc:=1234567890;

 SetLength(Dane.Moje1.Tablica,2); {dynamiczne zdefiniowanie wielkości tablicy}

 Dane.Moje1.Tablica[0]:='PIERWSZY element tablicy';
 Dane.Moje1.Tablica[1]:='DRUGI element tablicy';

 Dane.Moje2.Napis1:='Napis pierwszy';
 Dane.Moje2.Napis2:='Napis drugi';
 Dane.Moje2.Cena:=234;

 SetLength(Dane.Moje2.Tabela,3); {dynamiczne zdefiniowanie wielkości tablicy}
 Dane.Moje2.Tabela[0]:='Pierwsza linia tabeli';
 Dane.Moje2.Tabela[1]:='Druga linia tabeli';
 Dane.Moje2.Tabela[2]:='Trzecia linia tabeli';
end;

Niestety próba standardowego zapisu rekordu do pliku z wykorzystaniem "file of RekordCaly" nie działa - pojawia się komunikat:
"[DCC Error] Unit1.pas(51): E2155 Type 'RekordCaly' needs finalization - not allowed in file type"

Czy ktoś z Szanownych Grupowiczów (programistów) ma może jakiś "patent", jak taką strukturę (rekord) zapisać do pliku?

Dziękuję bardzo

Pozdrawiam

HamsterJack

0

stringa zapisujesz jako:
dlugość stringa
[znaki]

tablicę zapisujesz jako:
długość tablicy:
[dane]

czyli jeśi zapisujesz tablicę stringów to zapisujesz tak:
długość tablicy; [długość stringa;[znaki ze stringa]]

0
krwq napisał(a)

stringa zapisujesz jako:
dlugość stringa
[znaki]

tablicę zapisujesz jako:
długość tablicy:
[dane]

czyli jeśi zapisujesz tablicę stringów to zapisujesz tak:
długość tablicy; [długość stringa;[znaki ze stringa]]

Dzięki.

Czy mógłbyś rozwinąć zapis tablicy?

Jeszcze raz dzięki i pozdrawiam

HJ

0

myślałem, że już rozwinęłem. Nie sprecyzowałeś czy zapisujesz dane jako tekst, czy jako plik binarny

0

zastanówmy się, w jaki sposób zapisać dane o nieoznaczonej długości, gdzie raczej typ record stara się utrzymać i ewentualnie zapisać/odczytać dane o definiowanym wcześniej rozmiarze.

0
krwq napisał(a)

myślałem, że już rozwinęłem. Nie sprecyzowałeś czy zapisujesz dane jako tekst, czy jako plik binarny

Sorki wielkie - masz rację. Brak precyzji po mojej stronie.

Najchętniej zapisałbym jako binarkę. Ale tekst też by był dobry.

Dzięki.

0

Szanowni koledzy, przede wszystkim o ile wiem, jeżeli chce się zapisać dane do pliku jako całe rekordy, trzeba rekordy zaprojektować tak, by miały zawsze ten sam rozmiar!!!. Nie ma możliwości zapisu łańcucha o nieznanej długości, no bo skąd później aplikacja ma wiedzieć, jaką długość miały te łańcuchy?

type
{ deklaracja rekordu }
  TRecord = packed record
    FName : String[30];
    SName : String[30];
    Age : Byte;
  end;
 
procedure TMainForm.btnCreateClick(Sender: TObject);
var
  F: file of TRecord;
  Rec : TRecord;
begin
{ wypełnienie rekordu danymi }
  Rec.FName := 'Piotr';
  Rec.SName := 'Nowak';
  Rec.Age := 89;
  AssignFile(F, 'dane.dat');
  try
    Rewrite(F);  // utworzenie pliku
    Write(F, Rec); // dodanie rekordu
  finally
    CloseFile(F);
  end;
end;

Źródło: http://4programmers.net/Delphi/Kompendium/Rozdział_7

Jeżeli chcesz zapisać dane do pliku wykorzystując całe rekordy - określ precyzyjnie długość łańcuchów.

hamsterjack napisał(a)

Sorki wielkie - masz rację. Brak precyzji po mojej stronie.

Najchętniej zapisałbym jako binarkę. Ale tekst też by był dobry.

Może zastanów się najpierw nad sposobem zapisu. W temacie jest zapis rekordu, w ww cytacie jako plik binarny lub zwykłu tekstowy... Zastanów się najpierw, a później pytaj.

Może poczytaj o plikach INI, jeżeli zdecydujesz się na zwykłe pliki tekstowe. Pozdrawiam.

0

Dane rekordu można także zapisać w formacie XML. Wtedy długość tekstu nie ma znaczenia.

0
BoZzDoG napisał(a)

Szanowni koledzy, przede wszystkim o ile wiem, jeżeli chce się zapisać dane do pliku jako całe rekordy, trzeba rekordy zaprojektować tak, by miały zawsze ten sam rozmiar!!!. Nie ma możliwości zapisu łańcucha o nieznanej długości, no bo skąd później aplikacja ma wiedzieć, jaką długość miały te łańcuchy?

type
{ deklaracja rekordu }
  TRecord = packed record
    FName : String[30];
    SName : String[30];
    Age : Byte;
  end;
 
procedure TMainForm.btnCreateClick(Sender: TObject);
var
  F: file of TRecord;
  Rec : TRecord;
begin
{ wypełnienie rekordu danymi }
  Rec.FName := 'Piotr';
  Rec.SName := 'Nowak';
  Rec.Age := 89;
  AssignFile(F, 'dane.dat');
  try
    Rewrite(F);  // utworzenie pliku
    Write(F, Rec); // dodanie rekordu
  finally
    CloseFile(F);
  end;
end;

Źródło: http://4programmers.net/Delphi/Kompendium/Rozdział_7

Jeżeli chcesz zapisać dane do pliku wykorzystując całe rekordy - określ precyzyjnie długość łańcuchów.

hamsterjack napisał(a)

Sorki wielkie - masz rację. Brak precyzji po mojej stronie.

Najchętniej zapisałbym jako binarkę. Ale tekst też by był dobry.

Może zastanów się najpierw nad sposobem zapisu. W temacie jest zapis rekordu, w ww cytacie jako plik binarny lub zwykłu tekstowy... Zastanów się najpierw, a później pytaj.

Może poczytaj o plikach INI, jeżeli zdecydujesz się na zwykłe pliki tekstowe. Pozdrawiam.

Dzięki wielkie. Metodę zapisu precyzyjnie zdefiniowanych rekordów znam i ją stosuję w przypadku, w którym mogę zdefiniować precyzyjnie długości stringów czy rozmiar tabeli. W moim przypadku te wielkości muszą być definiowane dynamicznie. Największy problem, to zapis tablicy - zapis samego rekordu bez szczegółowej definicji długości stringów nie stwarza większego problemu.

Jeszcze raz dziękuję i pozdrawiam serdecznie
HamsterJack

0

napisze to dużymi literami bo do niektórych nie dociera to co się pisze JEŚLI CHCESZ ZAPISAĆ DO PLIKU COŚ CO NIE MA STAŁEGO ROZMIARU (STRING, TABLICA DYNAMICZNA, ITP) TO MUSISZ TO ZAPISAĆ RĘCZNIE. Nie ważne czy będziesz używał file of czy TFileStream czy jeszcze czegoś innego - nie da się tego zapisać zapisując całą strukturę. Trzeba wziąć każdy pojedyńczy element i zapisać zarówno jego długość jak i zawartość

0
TolkWimasz napisał(a)

Dane rekordu można także zapisać w formacie XML. Wtedy długość tekstu nie ma znaczenia.

Ale ma znaczenie długość pliku. XML to fajna sprawa, ale te znaczniki... Plik jest jak tasiemiec, widzisz początek, a później długo długo długo.....

hamsterjack napisał(a)

W moim przypadku te wielkości muszą być definiowane dynamicznie.

Skorzystaj może z plików amorficznych.

0

Witam Wszystkich

Dziękuje bardzo za pomoc w rozwiązaniu mojego problemu.

Rozwiązanie już znalazłem i gdyby ktoś z Szanownych Programistów miał podobny problem, to można skorzystać z biblioteki KBLib.

__http://code.google.com/p/kblib//kblib/

Plik do pobrania:
http://kblib.googlecode.com/files/KBLib2011-02-20.zip

Licencja:
MPL 1.1/GPL 2.0/LGPL 3.0

Jeszcze raz dziękuje za pomoc i przepraszam, jeśli "wnerwiłem" kilka osób, które chciały mi udzielić pomocy (nie jestem wytrawnym programistą).

Pozdrawiam
HamsterJack

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