Overview
INI files are simply text files with a format in order to save data in name and
value pairs. The name an value pair also usually called property. Properties
are grouped into sections, to make INI files able to hold duplicate names as
long as the names are unique in the given section.
[ATTACH]3785[/ATTACH]
Above is a sample of an INI file. The INI file’s name is myini.ini (I know, not
very intuitive name, but I hope it serves the purpose ). This INI file
contains three sections: TForm1, TForm2, and TForm3. As you can see, a
section is started by the section name wrapped by square brackets. The
section goes until another section starts or meeting the end of file.
Name and values are separated by equal sign (=). Everything (in a property)
before the equal sign are names, and everything (in a property) after the equal
sign are values. Some also refer to names as identifiers. So don’t get
confused if I mix the terms in the future. For example, in section number 1
(TForm1) we have a line
Quote
Caption=Caption Number 3
. For this line, Caption is the name and "Caption Number 3" is the value.
Limitations
Since INI file's main purpose was only to hold configuration data, it has some
limitations compared to some other file format.
Only one line for each name and value pair. Line in this case is marked
by CR (Carriage Return, ascii #13) and LF (Line Feed, ascii #10) pair. So
you cannot store multiple lines value with a name.
If you need to store multiple lines, then you have to break it into several
pairs of name-values.
No binary data. Since it is text file, you cannot directly store arbitrary
binary value. But you can store text format of the binary values and do
conversions when reading or writing. For example you can use
hexadecimal or Base64 format.
Reading and Writing INI Files with Delphi
To handle INI files, Delphi had provided a class specifically for this purpose.
The class' name is TIniFile, declared in IniFiles unit. This class even allows
you to store binary values into the ini file (it handles the conversion to and
from hexadecimal automatically, the only catch is that it limits the max size
of the binary values to 1023 bytes).
Reading a Single Value
TIniFile provides many methods to read a single value. The basic use is pretty
much the same. The main difference is only the value type they assigned for.
Basic Use:
AVariable := TIniFile.ReadXXXX(ASectionName, ATheName, ADefaultValue);
Note:
ASectionName: The section name from which we want to retrieve
the value.
ATheName: The name of the value to retrieve
ADefaultValue: This value will be returned if the section is or the
name is not found.
ReadXXXX can be one of the following methods (XXXX relates
with the value type):
ReadString
ReadInteger
ReadBool
ReadFloat
ReadDateTime
ReadDate
ReadTime
ReadBinaryStream
Writing a Single Value
To store a single value, TIniFile has already provided methods according to
value type.
Basic Use:
TIniFile.WriteXXXX(ASectionName, ATheName, AValue);
Note:
ASectionName: The section name to which we want to store the
value.
ATheName: The name of the value to be stored
AValue: The value to be stored
WriteXXXX can be one of the following methods (XXXX relates
with the value type):
WriteString
WriteInteger
WriteBool
WriteFloat
WriteDateTime
WriteDate
WriteTime
WriteBinaryStream
Getting Names of Sections
To get the names of all sections in an INI file, we can use
method ReadSections of TIniFile. E.g.:
uses
...
, IniFiles
...
procedure GetSectionNames(ASections: TStrings);
var
vIni: TIniFile;
begin
vIni := TIniFile.Create(IniFileName);
try
vIni.ReadSections(ASections);
finally
vIni.Free;
end;
end;
Reading All Values of a Section
We can also read all values stored in a section. For this we will need to pass
an valid instance of TStrings to contain the values. All values are in text
format.
uses
...
, IniFiles
...
procedure GetValuesOfSection(const ASection: string; AValues: TStrings);
var
vIni: TIniFile;
begin
vIni := TIniFile.Create(IniFileName);
try
vIni.ReadSectionValues(ASection, AValues);
finally
vIni.Free;
end;
end;
When the method returns, AValues will be filled with name value pairs
contained by the specified section.
Checking Availability of Values
Sometimes we need to know exactly whether a value or a section is really
exists. To check existence of a section we can use SectionExists method by
passing the section name to it. And to check a value we can
use ValueExists method by passing the section and the name of the value.
Implementation (Demo)
In the demo project we want to store the "content" of our form to an INI file
when we close the application, so that the next time it runs it will show the
last content. The key methods are:
private
function IniFile: string;
public
procedure ReadIniFile;
procedure SaveToIni;
Function IniFile
function IniFile is "calculating" the file name for our INI file. It returns ini file
with the name "myini.ini" from the same location with our program.
function TForm1.IniFile: string;
begin
Result := ExtractFilePath(ParamStr(0)) + 'myini.ini';
end;
Procedure ReadIniFile
This procedure reads information from our INI file into corresponding controls.
procedure TForm1.ReadIniFile;
var
vIni: TIniFile;
S : TStream;
vBmp: TBitmap;
begin
vIni := TIniFile.Create(IniFile);
try
Self.Caption := vIni.ReadString(Self.ClassName, 'Caption', '');
lblHeader.Caption := vIni.ReadString(Self.ClassName, 'Header', '');
Memo1.Text := vIni.ReadString(Self.ClassName, 'Memo', '');
cbbOption.ItemIndex := vIni.ReadInteger(Self.ClassName, 'Option', -1);
S := TMemoryStream.Create;
try
vIni.ReadBinaryStream(Self.ClassName, 'Picture', S);
if S.Size > 0 then
begin
S.Position := 0;
vBmp := TBitmap.Create;
try
vBmp.LoadFromStream(S);
Image1.Picture.Graphic := vBmp;
finally
vBmp.Free;
end;
end
else
Image1.Picture.Graphic := nil;
finally
S.Free;
end;
finally
vIni.Free;
end;
end;
Please note that the ability to load bitmap graphic here is only for illustration
purpose. I don't recommend to store graphics or any other large size values
into INI files.
Procedure SaveToIni
This procedure stores the content of our controls into the INI file.
procedure TForm1.SaveToIni;
var
vIni: TIniFile;
S : TStream;
begin
vIni := TIniFile.Create(IniFile);
try
vIni.WriteString(Self.ClassName, 'Caption', Self.Caption);
vIni.WriteString(Self.ClassName, 'Header', lblHeader.Caption);
vIni.WriteString(Self.ClassName, 'Memo', Memo1.Text);
vIni.WriteInteger(Self.ClassName, 'Option', cbbOption.ItemIndex);
vIni.ValueExists()
S := TMemoryStream.Create;
try
if Assigned(Image1.Picture.Graphic) then
begin
Image1.Picture.Graphic.SaveToStream(S);
S.Position := 0;
end;
vIni.WriteBinaryStream(Self.ClassName, 'Picture', S);
finally
S.Free;
end;
finally
vIni.Free;
end;
end;
To automatically read the INI file when starting,
place ReadIniFile in OnCreate event of the form. To automatically store
content into INI file when closing, place SaveToIni in OnClose event of the
form. And now it's ready.
Full source code of the demo project is attached. Feel free to use or improve
it. Just note that the "store bitmap" feature is just for illustration of storing
binary values. It will fail to load if you try to store bitmap image with size over
1023 bytes (TIniFile.WriteBinaryStream self imposed limitation). Again, I don't
recommend to store large size values in INI files.
[ATTACH]3786[/ATTACH]
Attached Thumbnails
Attached Files
IniFiles.zip 180.06KB 1929 downloads