Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[Delphi] Zapis obiektu do pliku

30 Paź 2011 14:34 1694 8
  • Poziom 14  
    Witam, na wstępie chciałbym zaznaczyć, iż podobne tematy będące już w sieci nie udzielają odpowiedzi na moje pytanie.
    Mianowicie: jak zapisać dość złożony obiekt (zawierający w sobie tablice pól wskazujące na inne klasy, które posiadają podklasy z nich dziedziczące) do pliku?

    Używając strumieni udaje mi się zapisać jedynie pojedyncze pola wskazując na nie bezpośrednio tzn.:
    Kod: delphi
    Zaloguj się, aby zobaczyć kod

    Natomiast zapis całego obiektu nie zapisuje pojedynczych pól, nie mówiąc już o tablicach czy bardziej złożonych strukturach, jak rekordy czy tablice obiektów.
    Kod: delphi
    Zaloguj się, aby zobaczyć kod

    Zawartość pliku zawiera jedynie kilka znaków i nazwę klasy, czyli z pewnością nie dane zawarte w tym obiekcie (ma on kilkaset zmiennych typu real i innych, tak więc w tych kilku znakach nie ma szans, że się to wszystko pomieści :D ). Moim zdaniem to jest wskaźnik na adres w pamięci programu oznaczającej początek obiektu. Jednak ja chciałbym mieć te dane zawarte w obiekcie w pliku.

    Zaznaczam, że operuje na TFileStream.

    Bardzo proszę o pomoc.
  • Moderator Programowanie
    Może ktoś powie, że to nie nowoczesne, że to archaizm itd. itp. ale..
    Rozważ zapis, za pomocą typu plikowego.
    Kod: delphi
    Zaloguj się, aby zobaczyć kod

    I zapisać Twój obiekt, pod pozycja 0 w pliku...
  • Poziom 32  
    Nie znam Delphi, ale daawno temu używałem Turbo Pascala i fantastycznej biblioteki TurboVision. Tam był specjalny mechanizm do zapisywania aktualnego stanu okienek do pliku - była to klasa TStreamRec, umożliwiająca, po odpowiednim przygotowaniu oczywiście, zapisywanie obiektów różnych klas i powiązań pomiędzy nimi do pliku.
    Wtrącam tę informację, bo Delphi to w sumie następca Turbo Pascala i pewnie podobny mechanizm też tutaj istnieje.
  • Poziom 14  
    arnoldziq niestety podany przez Ciebie sposób nie działa, gdyż kompilator po słowie "plik" spodziewa się przecinka, bądź dwukropka tj.
    [DCC Error] FigureClass.pas(1373): E2029 ',' or ':' expected but 'FILE' found
    krru - zdecydowanie wolałbym używać funkcji wbudowanych niż bibliotek.
  • Moderator Programowanie
    To co podałem, to prosta deklaracja... Oczywiście po słowie plik, powinien być dwukropek :) Poczytaj o typach plikowych.
    Ale podam też, rozwiązanie dla leniwych :P Możesz także dodać do swojej własnej klasy takę procedurę :
    Kod: delphi
    Zaloguj się, aby zobaczyć kod
  • Poziom 14  
    Taki kod już próbowałem i oto efekty jego działania (zawartość pliku):
    TPF0TPicture
    Przy czym obiekt zawiera kilka kB danych, więc kompresja jest niewyobrażalnie ogromna :D
  • Moderator Programowanie
    Daj tu deklarację tego swojego obiektu, zobaczymy.
  • Poziom 14  
    Jest ona bardzo rozbudowana - sama deklaracja to ok. 500 linii kodu, więc zamieszczę część tej deklaracji, ponieważ mam dość złożoną strukturę (kilka stopni dziedziczenia) tej klasy.
    Kod: delphi
    Zaloguj się, aby zobaczyć kod

    Później jest dalsze dziedziczenie, dużo tablic rekordów, dość to skomplikowane, ale przez to świetnie to wszystko funkcjonuje :D
  • Poziom 19  
    Próbując zapisać obiekt w taki sposób jak to chciałeś zrobić (i również jak koledzy sugerowali) - nie wyjdzie Ci to co byś chciał. Wskazywana zmienna jest tylko wskaźnikiem do struktury obiektu.

    Niestety klasa jest skomplikowaną strukturą, która oprócz zmiennych przechowujących wartości może przechowywać również wskaźniki do innych struktur, etc.

    Zapis klas (obiektów) do pliku nazywa się serializacją. Jeżeli chcesz wykonać to automatycznie dla dowolnego obiektu, musisz chyba napisać własną klasę do serializacji, która będzie korzystała z wbudowanego mechanizmu RTTI.

    Niestety w Delphi programowałem bardzo dawno temu i nie pamiętam dokładnie, ale na pewno są jakieś standardowe mechanizmy serializujące (np. w TStream masz WriteComponent i ReadComponent, ale do bardziej wymagających zastosowań trzeba przestudiować własnego serializatora lub helpera do tworzonej klasy, tak aby TStream mógł się do niego odwołać - na 99% implementacja interfejsu ISerializable.)