Board index » delphi » Storing a number of stringlists in the same file

Storing a number of stringlists in the same file

Hello All,

I managed to work out how to store string lists of variable lengths in a
text file a few days ago thanks to the help of the group.

I was simply going to use a separate file for each string list, but
looking at what I need to store, it seems there are going to be quite a
few files to store the different information types.

Is it possible to store them all in a single file one after the other (I
know I can write them one after another to the file no problems), but
then read them back into the application again - the main issue being
that each string list will be of a variable length?

This file might read thus :

Phone number information
Home : 2819478932174
Work : 348732894732
Mobile : 23987239847293
Address Information
Address Line 1
Address Line 2
Address Line 3
Address Line 4

But it could easily read thus, depending on what the user wants to store
:

Phone number information
Home : 2819478932174
Mobile : 23987239847293
Address Information
Address Line 1
Address Line 2

the tel numbers go into n telnumber variables, the address lines go into
n address line variables etc - there are six categories of variable
altogether, some might have one or anything up to 20 values. I want to
do different things with the different categories of variable so I can't
read it into one long string list.

Does anyone have nay suggestions?

Thanks in advance for any help,

Liam Healy

 

Re:Storing a number of stringlists in the same file


Quote
"L. Healy" <L.He...@occpsy.demon.co.uk> wrote in message
> I was simply going to use a separate file for each string list, but
> looking at what I need to store, it seems there are going to be quite a
> few files to store the different information types.

> Is it possible to store them all in a single file one after the other (I
> know I can write them one after another to the file no problems), but
> then read them back into the application again - the main issue being
> that each string list will be of a variable length?

procedure strmAppendStrings (aStream : tStream; anSL : tStrings);

var    i : integer; lth : LongInt; s : string;

begin
lth := anSL.Count;
aStream.Write (lth, SizeOf (lth));
for i := 0 to (anSL.Count - 1) do
    begin
    s := anSL [i];
    lth := Length (s);
    aStream.Write (lth, SizeOf (lth));
    if lth > 0
    then aStream.Write (s[1], lth);
    end;
end;

procedure strmLoadStrings (aStream : tStream; anSL : tStrings);

var i : integer; lth : LongInt; s : string;

begin
anSL.BeginUpdate;
try
    anSL.Clear;
    aStream.Read (lth, SizeOf (lth));
    for i := 0 to (lth - 1) do
        begin
        aStream.Read (lth, SizeOf (lth));
        SetLength (s, lth);
        if lth > 0
        then aStream.Read (s [1], lth);
        anSL.Add (s);
        end;
finally
    anSL.EndUpdate;
    end;
end;

Re:Storing a number of stringlists in the same file


Interesting
- you are just getting into writing your first 'mini-database'

Forget about StringLists - just think of each StringList as one long
string.

So now you have a number of 'long strings' of varying lengths that you
would like to store in one file.

At the begining of the file you could have an 'index' that holds the
Start of each 'long string' and its length - you could even store the
'file name' of each 'long string' in the 'index'

If you decrease the length of a 'long string' then it could go back in
its old 'slot' - if you increase the length then you could append it
to the end of the data file and mark the old 'slot' as dead.

You could write a simple routine to periodically clean up the file -
or you could look into re-using 'dead slots'

It is also a good idea to put a 'header' and 'footer' on each 'long
string' to check that all is correct.

None of this is very complicated - a simple TFileStream or
THandleStream and a _packed_ record type

At the end of it you will have a filing system that is capable of
storing _anything_ - a very useful thing indeed.

On Tue, 12 Mar 2002 16:58:50 +0000, "L. Healy"

Quote
<L.He...@occpsy.demon.co.uk> wrote:
>Hello All,

>I managed to work out how to store string lists of variable lengths in a
>text file a few days ago thanks to the help of the group.

>I was simply going to use a separate file for each string list, but
>looking at what I need to store, it seems there are going to be quite a
>few files to store the different information types.

>Is it possible to store them all in a single file one after the other (I
>know I can write them one after another to the file no problems), but
>then read them back into the application again - the main issue being
>that each string list will be of a variable length?

>This file might read thus :

>Phone number information
>Home : 2819478932174
>Work : 348732894732
>Mobile : 23987239847293
>Address Information
>Address Line 1
>Address Line 2
>Address Line 3
>Address Line 4

>But it could easily read thus, depending on what the user wants to store
>:

>Phone number information
>Home : 2819478932174
>Mobile : 23987239847293
>Address Information
>Address Line 1
>Address Line 2

>the tel numbers go into n telnumber variables, the address lines go into
>n address line variables etc - there are six categories of variable
>altogether, some might have one or anything up to 20 values. I want to
>do different things with the different categories of variable so I can't
>read it into one long string list.

>Does anyone have nay suggestions?

>Thanks in advance for any help,

>Liam Healy

Re:Storing a number of stringlists in the same file


In article <tdDoBKAKPjj8E...@occpsy.demon.co.uk>, "L. Healy"

Quote
<L.He...@occpsy.demon.co.uk> writes:
>the tel numbers go into n telnumber variables, the address lines go into
>n address line variables etc - there are six categories of variable
>altogether, some might have one or anything up to 20 values. I want to
>do different things with the different categories of variable so I can't
>read it into one long string list.

>Does anyone have nay suggestions?

declare an enumerated type to nominate the type of data ...

  TListDataType = (ldtHomePhone, ldtWorkPhone, ldtMobilePhone, ldtAddress, etc
etc

  Then have a few string reading and writing procedures ...

function ReadStreamInt(Stream : TStream) : integer;
{returns an integer from stream}
begin
  Stream.ReadBuffer(Result, SizeOf(Integer));
end;

function ReadStreamStr(Stream : TStream) : string;
{returns a string from the stream}
var
  StrLen : integer;
begin
  Result := '';
  {get length of string}
  StrLen := ReadStreamInt(Stream);
  {set string to get memory}
  SetLength(Result, StrLen);
  {read characters}
  Stream.Read(Result[1], StrLen);
end;

procedure WriteStreamInt(Stream : TStream; Num : integer);
{writes an integer to the stream}
begin
  Stream.WriteBuffer(Num, SizeOf(Integer));
end;

procedure WriteStreamStr(Stream : TStream; Str : string);
{writes a string to the stream}
var
  StrLen : integer;
begin
  {get length of string}
  StrLen := Length(Str);
  {write length of string}
  WriteStreamInt(Stream, StrLen);
  {write characters}
  Stream.Write(Str[1], StrLen);
end;

Then you can write to a stream ...

  Stream.Write(ListDataType, SizeOf(TListDataType));
  WriteStreamStr(Stream, StringList.Text);

.. for every element of your data. You may have to copy each set of elements to
an individual stringlist to get the StringList.Text, which is one string of all
your individual strings deleimited with CRLF. The stream write/read functions
write and copy the string length and then the characters. so all you have is a
number of elements ...

 type_of_data_value  strings_of_data_value

.. in the stream, then as the first write to your stream, write the number of
these elements. The first integer you read from the stream will then become
(-1) a limit specifier of a "for" loop which will read the rest into a
stringlist.

Alan Lloyd
alangll...@aol.com

Re:Storing a number of stringlists in the same file


Quote
> Does anyone have nay suggestions?

You sure came to a good spot for lots of suggestions.

Here's my two cents.  Use an INI file structure. The main key will be each
user's name.  Something like this.

[1]
Last=Smith
First=John
MI=L
WorkPhone=123-456-7890
HomePhone=345-678-9000
FaxPhone=321-9876
Address1=123 Any Street
Address2=Apt. 3A
City=My Town
State=NY
ZIP=12345-6789

[2]
Last=Jones
First=Mary
WorkPhone=555-1212
HomePhone=345-111-2222
Address1=45 67th St.
City=A Town with a Very long Name
State=BC
Country=Canada
FunnyData=some,good,data,that,you,can,store,in,a,stringlist,which_can_be,asl
ongasyouwant

Totally flexible. Well documented. Tried and true format. Best of all, you
can add fields later. You don't have to know all the fields, or their
lengths, when you set up your file initially.

You can use TINIFile from Delphi if you keep the file size down... perhaps
under 64kb. If you expect to end up with a larger file, use TBigINIfile
(freeware).

To read a variable, that itself is a stringlist, use CommaText.  e.g.

Funny := tstringlist.create;
Funny.commatext := INI.ReadString('2','FunnyData','');

now Funny[4] = 'you'
and Funny[5] = 'can'  etc.

Re:Storing a number of stringlists in the same file


I would recomend TBigIniFile, in any case. If you use TIniFile, and you want
to copy
the file, you could get some strange errors. TIniFile calls
WritePrivateProfileString, and the file might not be updated when you think
it should.

"Bob Richardson" <b...@pleasenospam.whidbey.com> skrev i melding
news:u8vkl4fh1bjd3b@corp.supernews.com...

Quote

> You can use TINIFile from Delphi if you keep the file size down... perhaps
> under 64kb. If you expect to end up with a larger file, use TBigINIfile
> (freeware).

Re:Storing a number of stringlists in the same file


On Thu, 14 Mar 2002 10:37:09 GMT, "Kjell-Olav Gr?ndalen"

Quote
<kgron...@online.no> wrote:
>I would recomend TBigIniFile, in any case. If you use TIniFile, and you want
>to copy
>the file, you could get some strange errors. TIniFile calls
>WritePrivateProfileString, and the file might not be updated when you think
>it should.

I would certainly *not* use TIniFile - it relies on Windows APIs and
is not really that 'controlable'

Writing ones own IniFile manager is a fairly simple task.

Quote

Re:Storing a number of stringlists in the same file


Hi,

Quote
>Here's my two cents.  Use an INI file structure. The main key will be each
>user's name.  Something like this.

>[1]
>Last=Smith
>First=John
>MI=L
>WorkPhone=123-456-7890
>HomePhone=345-678-9000
>FaxPhone=321-9876
>Address1=123 Any Street
>Address2=Apt. 3A
>City=My Town
>State=NY
>ZIP=12345-6789

>[2]
>Last=Jones
>First=Mary
>WorkPhone=555-1212
>HomePhone=345-111-2222
>Address1=45 67th St.
>City=A Town with a Very long Name
>State=BC
>Country=Canada
>FunnyData=some,good,data,that,you,can,store,in,a,stringlist,which_can_be,asl
>ongasyouwant

Thanks for this Bob (and others). This sounds closer to home.

I can store this information in the format above, no problem. What you
suggest sounds right, but I am struggling still - Delphi help is
painting an answer shaped hole - but no answer - it is difficult if you
haven't seen what the code to do this looks like. I also found and
downloaded TbigIniFile - but can't locate an answer in there either.

I suppose what I need is to be able to say : find 'Country=' then
whatever comes after it in the same line assign to a variable :
'countrystring'. I am quiet happy to hard code it the long way. So  just
read in the value 'Canada' and display it as a label on a form under a
heading - 'Favourite Countries of Mine' (for example). I can all do all
of this but I just can't figure out how to write the code to find
whatever value for 'Canada' the user has put in.

Once I see some code I usually work it out. But I can't find any working
examples.

Liam Healy

Re:Storing a number of stringlists in the same file


Quote
"L. Healy" <L.He...@occpsy.demon.co.uk> wrote in message
> I suppose what I need is to be able to say : find 'Country=' then
> whatever comes after it in the same line assign to a variable :
> 'countrystring'. I am quiet happy to hard code it the long way. So  just
> read in the value 'Canada' and display it as a label on a form under a
> heading - 'Favourite Countries of Mine' (for example). I can all do all
> of this but I just can't figure out how to write the code to find
> whatever value for 'Canada' the user has put in.

If the string list lines have the form <name>=<value> then use the Values
property, e.g.

    country := aStringList.Values ['Country'];

Other Threads