?
Solved

Save class to file

Posted on 2005-04-27
7
Medium Priority
?
259 Views
Last Modified: 2010-04-05
Hi all,

I've a short question but first i'll explain my problem. I've a few classes who are 'linked' to each other. Now i want to store these classes in one single (binairy)file. Is that possible? Is there maybe a component?

I know that's possible with records (File Of Record).

Please help me!

Greetz,

Sander
0
Comment
Question by:KiwiFreaK
  • 3
5 Comments
 
LVL 5

Expert Comment

by:paulb1989
ID: 13880916
You can save classes using TWriter and read them using TReader. It is easiest if you use classes derived from TComponent so you can use the WriteComponent method.
0
 
LVL 17

Accepted Solution

by:
TheRealLoki earned 600 total points
ID: 13881560
here's a complete example I wrote for you on how to load and save your owncustom defined classes to a file

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, contnrs; // for TObjectList - which automatically frees class objects in its list when you delete them - Loki

type TMyClass = class
    public
        name: string;
        age: integer;
        address: string;
        procedure SaveToStream(Stream: TStream);
        procedure LoadFromStream(Stream: TStream);
        constructor Create;
    end;

type
  TForm1 = class(TForm)
    bLoad: TButton;
    bSave: TButton;
    OpenDialog1: TOpenDialog;
    eName: TEdit;
    eAddress: TEdit;
    eAge: TEdit;
    bAddToMyList: TButton;
    Memo1: TMemo;
    bShowList: TButton;
    SaveDialog1: TSaveDialog;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure bLoadClick(Sender: TObject);
    procedure bSaveClick(Sender: TObject);
    procedure bAddToMyListClick(Sender: TObject);
    procedure bShowListClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    MyList: TObjectList;
    procedure LoadMyClassesFromFile;
    procedure SaveMyClassesToFile;
  end;

var
  Form1: TForm1;

IMPLEMENTATION

{$R *.DFM}

{ TMyClass }

constructor TMyClass.Create;
    begin
        inherited create;
        Name := '';
        Age := 0;
        Address := ''; //these are already blank, but i'm just showing where to put defaults
    end;

procedure TMyClass.LoadFromStream(Stream: TStream);
    var
        len: integer;
    begin
        Stream.Read(len, sizeof(len)); // get length of name
        Setlength(self.Name, len); // we need to make the string the right size to hold the data
        Stream.Read(self.Name[1], len); // read the name
        Stream.Read(self.Age, sizeof(self.Age)); // get age
        Stream.Read(len, sizeof(len)); // get length of address
        Setlength(self.Address, len); // we need to make the string the right size to hold the data
        Stream.Read(self.Address[1], len); // read the address
    end;

procedure TMyClass.SaveToStream(Stream: TStream);
    var
        len: integer;
    begin
        len := length(self.Name); // get the length of the name
        Stream.Write(len, sizeof(len)); // write length of name
        Stream.Write(self.Name[1], len); // write the name
        Stream.Write(self.Age, sizeof(self.Age)); // get age
        len := length(self.Address); // get the length of the address
        Stream.Write(len, sizeof(len)); // write length of address
        Stream.Write(self.Address[1], len); // write the address
    end;

procedure TForm1.FormCreate(Sender: TObject);
    begin
        MyList := TObjectList.Create;
    end;

procedure TForm1.FormDestroy(Sender: TObject);
    begin
        MyList.Clear;
        MyList.Free;
    end;

procedure TForm1.LoadMyClassesFromFile;
    var
        fs: TStream;
        total: integer;
        i: integer;
        newitem: TMyClass;
    begin
        MyList.Clear;
        if OpenDialog1.Execute then
        begin
            fs := TFileStream.Create(OpenDialog1.Filename, fmOpenRead);
            try
                fs.Read(total, sizeof(total)); // how many objects are in the file
                for i := 1 to total do
                begin
                    newitem := TMyClass.Create;
                    newitem.LoadFromStream(fs); // have each item load itself
                    MyList.Add(newitem); // add it to our list
                end;
            finally
                fs.free;
            end;
        end;
    end;

procedure TForm1.SaveMyClassesToFile;
    var
        fs: TStream;
        total: integer;
        i: integer;
        newitem: TMyClass;
    begin
        if SaveDialog1.Execute then
        begin
            fs := TFileStream.Create(SaveDialog1.Filename, fmCreate);
            try
                total := MyList.Count;
                fs.Write(total, sizeof(total)); // how many objects to save to file
                for i := 0 to pred(total) do
                  TMyClass(MyList[i]).SaveToStream(fs); // have each item save itself
            finally
                fs.free;
            end;
        end;
    end;

procedure TForm1.bLoadClick(Sender: TObject);
    begin
        LoadMyClassesFromFile;
    end;

procedure TForm1.bSaveClick(Sender: TObject);
    begin
        SaveMyClassesToFile;
    end;


procedure TForm1.bAddToMyListClick(Sender: TObject);
    var
        newitem: TMyClass;
    begin
        newItem := TMyClass.Create;
        newitem.Name := eName.Text;
        newitem.Age := StrToIntDef(eAge.Text, 0);
        newitem.Address := eAddress.Text;
        MyList.Add(newitem);
    end;

procedure TForm1.bShowListClick(Sender: TObject);
    var
        i: integer;
    begin
        memo1.lines.clear;
        for i := 0 to pred(MyList.Count) do
          memo1.lines.add(
        TMyClass(MyList[i]).name + ' : ' +
        IntToStr(TMyClass(MyList[i]).age) + ' : ' +
        TMyClass(MyList[i]).address);
       
    end;

end.




**************** FORM FOLLOWS *****************

object Form1: TForm1
  Left = 274
  Top = 213
  Width = 869
  Height = 623
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  PixelsPerInch = 96
  TextHeight = 13
  object bLoad: TButton
    Left = 96
    Top = 40
    Width = 75
    Height = 25
    Caption = 'bLoad'
    TabOrder = 0
    OnClick = bLoadClick
  end
  object bSave: TButton
    Left = 96
    Top = 80
    Width = 75
    Height = 25
    Caption = 'bSave'
    TabOrder = 1
    OnClick = bSaveClick
  end
  object eName: TEdit
    Left = 312
    Top = 48
    Width = 121
    Height = 21
    TabOrder = 2
    Text = 'eName'
  end
  object eAddress: TEdit
    Left = 312
    Top = 96
    Width = 121
    Height = 21
    TabOrder = 4
    Text = 'eAddress'
  end
  object eAge: TEdit
    Left = 312
    Top = 72
    Width = 121
    Height = 21
    TabOrder = 3
    Text = 'eAge'
  end
  object bAddToMyList: TButton
    Left = 448
    Top = 48
    Width = 89
    Height = 25
    Caption = 'bAddToMyList'
    TabOrder = 5
    OnClick = bAddToMyListClick
  end
  object Memo1: TMemo
    Left = 96
    Top = 120
    Width = 257
    Height = 153
    Lines.Strings = (
      'Memo1')
    TabOrder = 6
  end
  object bShowList: TButton
    Left = 448
    Top = 88
    Width = 89
    Height = 25
    Caption = 'bShowList'
    TabOrder = 7
    OnClick = bShowListClick
  end
  object OpenDialog1: TOpenDialog
    Left = 192
    Top = 72
  end
  object SaveDialog1: TSaveDialog
    Left = 232
    Top = 72
  end
end
0
 

Author Comment

by:KiwiFreaK
ID: 14896489
Thanks for you answer and sorry for my late reply but; How can i save these classes in one file? Is that possible?


TAgeClass = class
              age : Integer;
              dateofbirth : string;
              cityofbirth : string[30];
              constructor Create;
            end;
TMyClass = class
    public
        name: string;
        age : TAgeClass;
        address: string;
        procedure SaveToStream(Stream: TStream);
        procedure LoadFromStream(Stream: TStream);
        constructor Create;
    end;

0
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 14915479
Do you want 1 TMyClass in a file? or many TMYClass'es in the file?
0
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 14915625
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, contnrs; // for TObjectList - which automatically frees class objects in its list when you delete them - Loki

type TAgeClass = class
        age : Integer;
        dateofbirth : string;
        cityofbirth : string[30];
        constructor Create;
    end;

type TMyClass = class
    public
        name: string;
        age: TAgeClass;
        address: string;
        procedure SaveToStream(Stream: TStream);
        procedure LoadFromStream(Stream: TStream);
        constructor Create;
        destructor Destroy; override;
    end;

type
  TForm1 = class(TForm)
    bLoad: TButton;
    bSave: TButton;
    OpenDialog1: TOpenDialog;
    eName: TEdit;
    eAddress: TEdit;
    eAge: TEdit;
    bAddToMyList: TButton;
    Memo1: TMemo;
    bShowList: TButton;
    SaveDialog1: TSaveDialog;
    eDateOfBirth: TEdit;
    eCityOfBirth: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure bLoadClick(Sender: TObject);
    procedure bSaveClick(Sender: TObject);
    procedure bAddToMyListClick(Sender: TObject);
    procedure bShowListClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    MyList: TObjectList;
    procedure LoadMyClassesFromFile;
    procedure SaveMyClassesToFile;
  end;

var
  Form1: TForm1;

IMPLEMENTATION

{$R *.DFM}

{ TMyClass }

constructor TMyClass.Create;
    begin
        inherited create;
        Name := '';
        age := TAgeClass.Create;
        Address := ''; //these are already blank, but i'm just showing where to put defaults
    end;

destructor TMyClass.Destroy;
    begin
        Age.Free;
        inherited Destroy;
    end;

procedure TMyClass.LoadFromStream(Stream: TStream);
    var
        len: integer;
    begin
        Stream.Read(len, sizeof(len)); // get length of name
        Setlength(self.Name, len); // we need to make the string the right size to hold the data
        Stream.Read(self.Name[1], len); // read the name
// read age
        Stream.Read(self.Age.Age, sizeof(self.Age.Age)); // get age
        Stream.Read(len, sizeof(len)); // get length of address
        Setlength(self.Age.dateofbirth, len); // we need to make the string the right size to hold the data
        Stream.Read(self.Age.dateofbirth[1], len); // read the address
        Stream.Read(len, sizeof(len)); // get length of address
        Setlength(self.Age.cityofbirth, len); // we need to make the string the right size to hold the data
        Stream.Read(self.Age.cityofbirth[1], len); // read the address

        Stream.Read(len, sizeof(len)); // get length of address
        Setlength(self.Address, len); // we need to make the string the right size to hold the data
        Stream.Read(self.Address[1], len); // read the address
    end;

procedure TMyClass.SaveToStream(Stream: TStream);
    var
        len: integer;
    begin
        len := length(self.Name); // get the length of the name
        Stream.Write(len, sizeof(len)); // write length of name
        Stream.Write(self.Name[1], len); // write the name
// write age
        Stream.Write(self.Age.Age, sizeof(self.Age.Age)); // write age
        len := length(self.Age.dateofbirth); // get the date of birth
        Stream.Write(len, sizeof(len)); // write the date of birth
        Stream.Write(self.Age.dateofbirth[1], len); // write the date of birth
        len := length(self.age.cityofbirth); // get the length of city of birth
        Stream.Write(len, sizeof(len)); // write length of city of birth
        Stream.Write(self.age.cityofbirth[1], len); // write the city of birth

        len := length(self.Address); // get the length of the address
        Stream.Write(len, sizeof(len)); // write length of address
        Stream.Write(self.Address[1], len); // write the address
    end;

procedure TForm1.FormCreate(Sender: TObject);
    begin
        MyList := TObjectList.Create;
    end;

procedure TForm1.FormDestroy(Sender: TObject);
    begin
        MyList.Clear;
        MyList.Free;
    end;

procedure TForm1.LoadMyClassesFromFile;
    var
        fs: TStream;
        total: integer;
        i: integer;
        newitem: TMyClass;
    begin
        MyList.Clear;
        if OpenDialog1.Execute then
        begin
            fs := TFileStream.Create(OpenDialog1.Filename, fmOpenRead);
            try
                fs.Read(total, sizeof(total)); // how many objects are in the file
                for i := 1 to total do
                begin
                    newitem := TMyClass.Create;
                    newitem.LoadFromStream(fs); // have each item load itself
                    MyList.Add(newitem); // add it to our list
                end;
            finally
                fs.free;
            end;
        end;
    end;

procedure TForm1.SaveMyClassesToFile;
    var
        fs: TStream;
        total: integer;
        i: integer;
        newitem: TMyClass;
    begin
        if SaveDialog1.Execute then
        begin
            fs := TFileStream.Create(SaveDialog1.Filename, fmCreate);
            try
                total := MyList.Count;
                fs.Write(total, sizeof(total)); // how many objects to save to file
                for i := 0 to pred(total) do
                  TMyClass(MyList[i]).SaveToStream(fs); // have each item save itself
            finally
                fs.free;
            end;
        end;
    end;

procedure TForm1.bLoadClick(Sender: TObject);
    begin
        LoadMyClassesFromFile;
    end;

procedure TForm1.bSaveClick(Sender: TObject);
    begin
        SaveMyClassesToFile;
    end;


procedure TForm1.bAddToMyListClick(Sender: TObject);
    var
        newitem: TMyClass;
    begin
        newItem := TMyClass.Create;
        newitem.Name := eName.Text;
        newitem.Age.age := StrToIntDef(eAge.Text, 0);
        newitem.Age.dateofbirth := eDateOfBirth.Text;
        newitem.Age.cityofbirth := eCityOfBirth.Text;
        newitem.Address := eAddress.Text;
        MyList.Add(newitem);
    end;

procedure TForm1.bShowListClick(Sender: TObject);
    var
        i: integer;
    begin
        memo1.lines.clear;
        for i := 0 to pred(MyList.Count) do
          memo1.lines.add(
          TMyClass(MyList[i]).name + ' : ' +
          IntToStr(TMyClass(MyList[i]).age.age) + ' : ' +
          TMyClass(MyList[i]).age.dateofbirth + ' : ' +
          TMyClass(MyList[i]).age.cityofbirth + ' : ' +
          TMyClass(MyList[i]).address);

    end;

{ TAgeClass }

constructor TAgeClass.Create;
    begin
        age := 0;
        dateofbirth := '';
        cityofbirth := '';
    end;

end.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
Suggested Courses

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question