INI文件的保存与加载
今天目标是通过INI文件的读写将当前的工程进行保存,同时实现对已有工程文件的读取。
起初的实现是打算通过txt文件的读写完成该任务,通过学习了解到Delphi中含有对INI文件操作的封装,相对于已有的API总比自己写的要安全稳定快捷的多。
- INI基础API
关于INI文件的具体介绍请移步百度,这里只写我看到的样子。该文件主要分三个部分:section、key、value。通过检索节可以得到键、通过键再检索出值很直白。
相关API
- 打开文件
ini:TMemIniFile;
// 我这里只需要保存数据,对格式没有要求所以采用了TMemIniFile类。这个有点像C语言文件操作里的文件指针。
Delphi(Pascal)
ini := TMemIniFile.Create(Path);
/************************************/
C
fp=fopen(filename,mode);
-
写数据
ini.WriteInteger(const Section, Ident: string; Value: Longint);
ini.WriteString(const Section, Ident, Value: String);
等等,我基本上只使用了这两个用来写,完成数据写入在最后加上ini.UpdateFile;数据才真正写入文件,然后再ini.Free掉就可以了。 -
读数据
ini.ReadInteger(const Section, Ident: string;Default: Longint): Longint;
ini.ReadString(const Section, Ident,Default: string): string;
这里说明,函数的原型不是长成上面写的这个样子,我这样写主要是为了方便我自己认清参数的含义,如果想看原型的可以再Delphi里自己翻出来。
- 关闭文件
直接Free
//以保存工程为示例
procedure SaveProject;
var
i,j:integer;
ini:TMemIniFile;
savePath:string;
begin
//获取路径
if proj.Path = '' then
begin
if mainForm.SaveDialog1.Execute then
begin
if extractfileExt(mainForm.savedialog1.FileName)<>'.scl' then //判断文件名后缀是否为.scl
mainForm.SaveDialog1.FileName := ChangeFileExt(mainForm.SaveDialog1.FileName,'.scl'); //不是的话修改后缀为.scl
proj.Path := MainForm.SaveDialog1.FileName;
MainForm.StatusBar1.Panels[3].Text := proj.Path;
end;
end;
savePath := proj.Path;
if savePath <> '' then
begin //开始保存项目
ini := TMemIniFile.Create(proj.Path);
ini.WriteString('project','name',proj.Path);
ini.WriteInteger('project','numberOfPage',mainForm.TabSet1.Tabs.Count);
ini.WriteInteger('project','numberOfObject',ObjectList.Count);
ini.WriteInteger('project','screenWidth',proj.screenWidth);
ini.WriteInteger('project','screenHeight',proj.screenHeight);
ini.WriteInteger('project','screenK',proj.screenk);
ini.WriteInteger('project','Shape2.Width',MainForm.Shape2.Width);
ini.WriteInteger('project','Shape2.Left',MainForm.Shape2.Left);
ini.WriteInteger('project','Shape2.Top',MainForm.Shape2.Top);
ini.WriteInteger('project','Shape2.Height',MainForm.Shape2.Height);
ini.WriteDateTime('project','creatTime',now());
for i := 0 to mainForm.TabSet1.Tabs.Count-1 do
begin
ini.WriteString('page'+inttostr(i),'title',mainForm.TabSet1.Tabs.Strings[i]);
for j := 0 to FormList.Count-1 do
if (FormList[j] as TFormList).page = i then break;
with (FormList[j] as TFormList) do
begin
ini.WriteInteger('page'+inttostr(i),'page',page);
ini.WriteInteger('page'+inttostr(i),'left',left);
ini.WriteInteger('page'+inttostr(i),'width',width);
ini.WriteInteger('page'+inttostr(i),'top',top);
ini.WriteInteger('page'+inttostr(i),'height',height);
end;
end;
if (ObjectList <> nil)and(ObjectList.Count > 0) then
begin
for i := 0 to ObjectList.Count-1 do
begin
with ObjectList[i] as TDefObject do
begin
ini.WriteInteger('Object'+inttostr(ID),'ID',ID);
ini.WriteString('Object'+inttostr(ID),'Describe',Describe);
ini.WriteString('Object'+inttostr(ID),'Caption',Caption);
ini.WriteInteger('Object'+inttostr(ID),'Size',Font.Size);
ini.WriteString('Object'+inttostr(ID),'Align',Align);
ini.WriteInteger('Object'+inttostr(ID),'NumAlign',NumAlign);
ini.WriteInteger('Object'+inttostr(ID),'kLeft',kLeft);
ini.WriteInteger('Object'+inttostr(ID),'kWidth',kWidth);
ini.WriteInteger('Object'+inttostr(ID),'kTop',kTop);
ini.WriteInteger('Object'+inttostr(ID),'kHeight',kHeight);
ini.WriteInteger('Object'+inttostr(ID),'page',Page);
end;
end;
end;
ini.UpdateFile;
ini.Free;
MainForm.StatusBar1.Panels[0].Text := '已保存';
MainForm.StatusBar1.Panels[3].Text := proj.Path;
proj.saveFlag := 0;
end;
ShowMessage('保存完成');
end;
通过上述的API已经可以开始对文件进行读写,为了让软件能更友好的选择文件读写的路径,这里通过调用SaveDialog1和OpenDialog1两个控件实现保存路径和打开路径的选择。太具体的我也不会,我只设置了Filter属性方便文件的过滤。
- 具体流程:
通过Execute属性打开对话框并在程序中产生阻断,当用户点击确定时会返回True
通过上述API应该可以完成基本的保存和读取功能了,至于写的东西就是工程中创建的控件的数据按照固定的格式依次写入,读取加载也一样。读取时需要严格把控脚标的偏移防止超出报错。