Solved

Save counters

Posted on 2003-12-02
21
492 Views
Last Modified: 2010-04-05
Hi,

I've an application that records lots of live data.
I need to record those data on file. So, that later when I re-enter I can resume this data.
It's simple data, like file transfer speed.
I was planning to use a Paradox table, but for that I need to use BDE or any other DB tool, which increases the size of it, right?
I think that just writing to a File is enought?
Does anyone knows the best way to do it?
Thanks,
Luis
0
Comment
Question by:lfgmartins
  • 6
  • 5
  • 3
  • +5
21 Comments
 
LVL 1

Expert Comment

by:roknjohn
ID: 9861377
If the data is in controls on a form, i use this method to read/write the values to a INI file.  Just set the Tag property to a non-zero value for each control that you want to save.   I do this at design time.  Then call LoadControls in the form's FormShow/Create and call SaveControls in FormClose or in a ButtonClick.  Pass the Form (self) or other container (panel) as the parent argument.

Note: there are overloaded versions of SaveControls and LoadControls;

interface
  procedure LoadControl(Control : TControl; Value : String);
  function ControlText(Control : TControl) : string;
  function ChildControlText(ControlName : String; Parent : TWinControl) : string;
  procedure SetChildControlText(ControlName : String; Parent : TWinControl; Value : string);
  procedure LoadControls(IniFile : TIniFile; Section : String; Parent : TWinControl); overload;
  procedure SaveControls(IniFile : TIniFile; Section : String; Parent : TWinControl); overload;
  procedure LoadControls(InputFile : String; Section : String; Parent : TWinControl); overload;
  procedure SaveControls(InputFile : String; Section : String; Parent : TWinControl); overload;
implementation

procedure LoadControl(Control : TControl; Value : String);
begin
  if Control is TEdit then
    TEdit(Control).Text := Value;
  if Control is TSpinEdit then
    TSpinEdit(Control).Text := Value;
  if Control is TComboBox then
    with TComboBox(Control) do begin
      if Style=csDropDownList then
        ItemIndex := Items.IndexOf(Value)
      else
        Text := Value;
    end;
  if Control is TCheckBox then
    TCheckBox(Control).Checked := Pos(Copy(Value,1,1),'YyXxTt1') > 0;
  if Control is TRadioButton then
    TRadioButton(Control).Checked := Pos(Copy(Value,1,1),'YyXxTt1') > 0;
  if Control is TStaticText then
    TStaticText(Control).Caption := Value;
  if Control is TRadioGroup then
    TRadioGroup(Control).ItemIndex := StrToInt(Value);
  if Control is TCustomListBox then
    TCustomListBox(Control).Items.CommaText := Value;
end;

function ControlText(Control : TControl) : string;
begin
  if Control is TEdit then
    Result := TEdit(Control).Text;
  if Control is TSpinEdit then
    Result := TSpinEdit(Control).Text;
  if Control is TComboBox then
    Result := TComboBox(Control).Text;
  if Control is TCheckBox then
    if TCheckBox(Control).Checked then
      Result := 'Y'
    else
      Result := 'N';
  if Control is TRadioButton then
    if TRadioButton(Control).Checked then
      Result := 'Y'
    else
      Result := 'N';
  if Control is TStaticText then
    Result := TStaticText(Control).Caption;
  if Control is TRadioGroup then
    Result := IntToStr(TRadioGroup(Control).ItemIndex);
  if Control is TCustomListBox then
    Result := TCustomListBox(Control).Items.CommaText;
end;

function ChildControlText(ControlName : String; Parent : TWinControl) : string;

  procedure ReadChildren(var Found : boolean; var Text : string; Control : TWinControl);
  var
    i : integer;
  begin
    with Control do
      for i := 1 to ControlCount do
        if Controls[i-1] is TWinControl then  //recursive iteration thru children
          if not Found then
            ReadChildren(Found,Text,TWinControl(Controls[i-1]));
    if Control.Name = ControlName then begin
      Text := ControlText(Control);
      Found  := True;
    end;
  end;

var
  Found : Boolean;
  Text : String;

begin
  Found := False;
  Text := '';
  ReadChildren(Found,Text,Parent);
  Result := Text;
end;

procedure SetChildControlText(ControlName : String; Parent : TWinControl; Value : string);

  procedure ReadChildren(var Found : boolean; Control : TWinControl);
  var
    i : integer;
  begin
    with Control do
      for i := 1 to ControlCount do
        if Controls[i-1] is TWinControl then  //recursive iteration thru children
          if not Found then
            ReadChildren(Found,TWinControl(Controls[i-1]));
    if Control.Name = ControlName then begin
      LoadControl(Control,Value);
      Found  := True;
    end;
  end;

var
  Found : Boolean;

begin
  Found := False;
  ReadChildren(Found,Parent);
end;

procedure SaveControls(IniFile : TIniFile; Section : String; Parent : TWinControl);
var
  i : integer;
begin
  with Parent do
    for i := 1 to ControlCount do
      if Controls[i-1] is TWinControl then  //recursive iteration thru children
        SaveControls(IniFile, Section, TWinControl(Controls[i-1]));
  if Parent.Tag<>0 then
    IniFile.WriteString(Section, Parent.Name, ControlText(Parent));
end;

procedure LoadControls(IniFile : TIniFile; Section : String; Parent : TWinControl);
var
  i : integer;
begin
  with Parent do
    for i := 1 to ControlCount do
      if Controls[i-1] is TWinControl then  //recursive iteration thru children
        LoadControls(IniFile, Section, TWinControl(Controls[i-1]));
  if Parent.Tag<>0 then
    LoadControl(Parent,IniFile.ReadString(Section, Parent.Name, ControlText(Parent)));
end;

procedure LoadControls(InputFile : String; Section : String; Parent : TWinControl);
var
  IniFile : TIniFile;
begin
  IniFile := TIniFile.Create(InputFile);
  try
    LoadControls(IniFile,Section,Parent);
  finally
    IniFile.Free;
  end;
end;


procedure SaveControls(InputFile : String; Section : String; Parent : TWinControl);
var
  IniFile : TIniFile;
begin
  IniFile := TIniFile.Create(InputFile);
  try
    SaveControls(IniFile,Section,Parent);
  finally
    IniFile.Free;
  end;
end;
0
 
LVL 1

Expert Comment

by:roknjohn
ID: 9861415
How are you storing the data in memory?  TEdits, TStringLists, variables, arrays, etc?

There are many options to write data to a file.  Depending on your data, you may not need a database.

I agree, with you about the BDE.  I haven't used it in many years.  It was always a HEADACHE.  Now, I only use ADO.

0
 
LVL 2

Expert Comment

by:odissey1
ID: 9861438
Hi  roknjohn,

He said a LOT of LIVE data. Let's assume 1 MB of integer numbers  per second and ~1 GB total :). If this is the case, the INI file is no good. I would go with a Binary file and block write / block read buffers.

Regards,
odissey1
0
 
LVL 2

Expert Comment

by:odissey1
ID: 9861518
Hi  lfgmartins,

If you comfortable with databases, but do not want BDE overhead then use TkbmMemTable.
http://www.components4programmers.com/products/kbmmemtable/
This is very fast  (probably fastest one), , no BDE required, works like ordinary TTable and you can save / restore it to HDD. But if you need just a basic save structure, use PackedRecord and block write it to a binary file - you can't go faster. Or you can?

Regards,
odissey1  
0
 
LVL 1

Expert Comment

by:roknjohn
ID: 9861563
Without knowing the actual structure that he is using to hold the data (and quantity), it may be hard to determine the EASIEST, FASTEST, or MOST CONSERVATIVE method to use.

If the data is very granular, i.e. a lot of variables (integer, float, shortstring) then he may have to write them one at a time to a file.  Or, place their declarations in a Record structure and write the whole thing at once.

If it is in large arrays, then you could use the blockread/blockwrite or FileRead/FileWrite.  I use the later with file handles, even though many programmers do not.

0
 
LVL 8

Expert Comment

by:gmayo
ID: 9861584
I agree on the INI file comment - too slow once it gets large, and is limited in size (32k, 64k? can't remember). TReader and TWriter are good (in association with TFileStream).

Geoff M.
0
 
LVL 1

Expert Comment

by:roknjohn
ID: 9861672
"LOT" is a relative term.  I'll wait for Luis to quantify his question.  :-)

But to defend INI files around the World...

The routine that I posted above are VERY useful for storing a form full of controls.  I use them all the time.  All I have to do is set  the Tag property for those controls that are to be persisted to disk and add two calls.

procedure TForm1.FormShow(Sender: TObject);
begin
  LoadControls('Project1.ini',Name,Self);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  SaveControls('Project1.ini',Name,Self);
end;

I use similay functions to Load and Save the form's position to the INI as well.
0
 

Author Comment

by:lfgmartins
ID: 9861739
Thank you all for your replys.
I cannot see these great solutions right now, sry. I'll see it tomorrow.
My information is very small, less than 1 MB, because when I save the data I overwrite the all file. Perhaps something like a INI, but that I can write like a record structure?
Regards,
Luis
0
 
LVL 1

Expert Comment

by:roknjohn
ID: 9861812
I have a recordlist class that has LoadFromFile and SaveToFile if you are storing in mulitple record structures.  If you only have one huge record (with static members) you can just write it with one FileWrite or BlockWrite statement.

procedure TForm1.SaveToFile(Filename : string);
var
  F : File;
begin
  AssignFile(F,FileName);
  Rewrite(F,1);
  BlockWrite(F,MyHugeRecord,Sizeof(MyHugeRecord));
  CloseFile(F);
end;
0
 
LVL 2

Expert Comment

by:odissey1
ID: 9861968
Hi lfgmartins,

There is a bottleneck with
BlockWrite(F,MyHugeRecord,Sizeof(MyHugeRecord));
if Sizeof(MyHugeRecord) > your HDD buffer size. On most UDMA today this is 2MB. Try to set BufferSize less than this value (smaller chunks of data).

Regards,
odissey1

to roknjohn:
Now you joined a BlockWrite clan! :)
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 1

Expert Comment

by:roknjohn
ID: 9862011
Odi: I'm more of a "BlockHead"! That was pasted from some old code that I have.  I still like using the handles & FileWrite.  I don't know...my code just looks cleaner or something.  I guess I'm really "bi," then.  :-D
0
 
LVL 2

Expert Comment

by:odissey1
ID: 9862014
To roknjohn,

>But to defend INI files around the World...

I found easy way to keep controls persistent in INI: StorageLibrary from deepsoftware.ru. Add to project and click few buttons. No Tag required.

regards,
odissey1
P.S. Now I joined INI clan too! :)

0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 9863647

Just a side note....

If your using ini files based on the API implementation, ie TIniFile which calls

GetPrivateProfileInt
GetPrivateProfileSection
GetPrivateProfileSectionNames
etc....

then the limit is 64 KB, but problems can occur when the size is over 32k. Point of reference for this is MSDN article Q78346.

That is not to say that you can't use an ini file format. For example, delphi has the TMemIniFile, which is based on TStrings behind the scenes, and can easily handle files over 1MB in size, albeit in memory. If the memory overhead is not an issue, then this provides a clean solution, as it is fast (in memory), and allows you to manually persist the data on demand if need be (using the UpdateFile method)

Regards,
Russell

ps: Ini's still have their place ;-)




0
 
LVL 33

Assisted Solution

by:Slick812
Slick812 earned 50 total points
ID: 9864157
hello lfgmartins, Writting your data to file will depend on what and how your "Data" is made up, and how you will want to Get the data once it is in the file, and several other factors, you can create files with any data segments you need, but if you have different sorts of Data (integer, real, TRect, String type, Bitmap, just some chunk of bytes that has no type), you will need a system to keep tract of what and where your data segments are in your file, to be able to read them out later. . . I have a web page with some examples of creating your own custom data files at -

http://www.angelfire.com/hi5/delphizeus/customfiles.html

but it may not be so easy if you do not have some way to organize the data
ask questions if you need more info
0
 
LVL 2

Expert Comment

by:odissey1
ID: 9864815
Hi Slick812,

Thanks for link. Very interesting site.

Regards,
odissey1
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 9864817
not sure, what should be saved here,
question is to vage to provide a fitting answer

please explain a bit more

meikl ;-)
0
 

Author Comment

by:lfgmartins
ID: 9871013
Hi all,

Thank you all for your replies. I think we've explored great solutions here. Some that is good for one case other for others.
I liked particularly the one from gmayo about the Treader and Twriter and the TFileStream. On the Delphi help TReader and TWriter are associated with TStream. What are the differences between TStream and TFileStream?
My data are essentially Strings and Longwords. How can I write them with TWriter and then read it again with TReader? Where does the TFileStream enter here?
I liked also from the website Slick812 sent. It'll be a great help for many people including me :)
Regards,
Luis
0
 
LVL 5

Expert Comment

by:Gwena
ID: 9871856
Hi :-)


I can make you a simple demo that will show you how to store strings/numbers into data files
and retrieve them easily...

You can read/write/alter/delete/replace data easily and call the data by name.

It's best if the data files are not too huge... a few MB is just fine.

If you want a demo let me know and I will make one where you can type the name of the data
file you wish to create into an edit... then type a string or a number to be stored into that file.
You can store the data under a variable name.... and then retrieve and display it by it's name..
it's all very easy and only takes a few lines of simple code :-)

ANY sort of data can be placed into the files...images/numbers/strings/other exe files/....whatever
0
 

Author Comment

by:lfgmartins
ID: 9875003
Hi Gwena,

If it doesn’t take you too much work, I'd like to have a demo.
I don't have great experience with files. So your demo it'll be perfect for learning.
Thank you for your time,
Luis
0
 
LVL 8

Accepted Solution

by:
gmayo earned 300 total points
ID: 9877795
Sorry, I've been away. An example of reading/writing:

var f : TFileStream;
w : TWriter;
r : TReader;
MyInt : longint;
MyStr : string;

// To write
f := TFileStream.Create('test.dat', fmCreate);
w := TWriter.Create(f, 1024);
w.WriteInteger(1234567);
w.WriteString('Hello, world!');
w.Free;
f.Free;

// To read
f := TFileStream.Create('test.dat', fmOpenRead);
r := TReader.Create(f, 1024);
MyInt := r.ReadInteger;
MyStr := r.ReadString;
r.Free;
f.Free;

Note that you should use exception handling around the r.ReadXXX because it can raise exceptions if it cannot read the data.

Geoff M.
0
 
LVL 5

Assisted Solution

by:Gwena
Gwena earned 150 total points
ID: 9879043
took about 15 minutes...

you have to right-click this link and choose 'save target as' because geocities
won't allow external links to files..

http://www.geocities.com/gacarpenter386/datafiles.zip

this demo includes source and a compiled exe...
I made it as simple as I could in 15 minutes.

If you need any more help just yell :-)

Oh... do read the readme.txt file in the zip.....
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
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…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

747 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now