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

[Delphi] Zapis obiektu do pliku

pgnige 30 Paź 2011 14:34 1604 8
  • #1 30 Paź 2011 14:34
    pgnige
    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.

    0 8
  • #2 30 Paź 2011 15:11
    arnoldziq
    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...

    0
  • #3 30 Paź 2011 15:40
    krru
    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.

    0
  • #4 30 Paź 2011 16:55
    pgnige
    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.

    0
  • #5 30 Paź 2011 17:07
    arnoldziq
    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

    0
  • #6 30 Paź 2011 17:43
    pgnige
    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

    0
  • #7 30 Paź 2011 18:08
    arnoldziq
    Moderator Programowanie

    Daj tu deklarację tego swojego obiektu, zobaczymy.

    0
  • #8 30 Paź 2011 18:33
    pgnige
    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

    0
  • #9 02 Lis 2011 12:22
    Luklukowaty
    Poziom 18  

    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.)

    0