发新话题
打印

[转载]利用DELPHI冲破INI文件的限制

[转载]利用DELPHI冲破INI文件的限制

Writer:夏昆冈
引用:
利用DELPHI冲破INI文件的限制

如果需要编写绿色软件,INI文件就是保存软件设置的最佳选择,虽然INI文件是一种非常古老的文件格式,但INI仍旧有着注册表无法取代的优势。Windows已经发展到了95/98,微软却并没有对INI进行进一步的支持,希望注册表能够完全替代她。INI和纯文本文件一样有着64K的限制,64K对于一般的应用是足够的,但如果您需要编写游戏菜单或其他要求储存较大量数据的程序时,INI的尺寸限制可能成为您的烦恼,也许您会考虑采用小型数据库,但在此之前不妨先尝试使用Delphi提供的TStringList来解决问题。

  首先创建一个Unit,并输入以下代码:
复制内容到剪贴板
代码:
 unit Unit1;

{$R-}

interface

uses Windows, Classes, Dialogs;

type

TExtIniFile = class(TObject) //extiniê? ±ê ×? INI?? ?t μ? à? ?1 Dí

private

FFileName: string;

FList: TStringList;

Str_Temp: string;

public

constructor Create(constFileName: string);

function ReadString(const Section: string; Ident: string; Default: string): string;

//?á è? ×? ·? ′?

function ReadInteger(const Section: string; Ident: string; Default: Longint):

Longint;

//?á è? êy ?μ

function ReadBoolean(const Section: string; Ident: string; Default: Boolean):

Boolean;

//?á è? 2? ??

procedure ReadSections(Strings: TStrings);

//?ì ?÷ è? 2? ?? μ? ?? 3?

procedure ReadIdents(const Section: string; Strings: TStrings);

//?ì ?÷ ?? ?¨ ?? ?ú μ? ?ü μ? ?? 3?

property FileName: string read FFileName;

procedure WriteString(const Section: string; Ident: string; Value: string);

//D′ ×? ·? ′?

procedure WriteInteger(const Section: string; Ident: string; Value: Integer);

//D′ êy ?μ

procedure WriteBoolean(const Section: string; Ident: string; Value: Boolean);

//D′ 2? ??

end;

implementation

uses SysUtils, Consts;

//?¨ ò? TExtIniFileμ? ′′ ?¨ ê? ?t

constructor TExtIniFile.Create(constFileName: string);

begin

FFileName := FileName;

FList := TStringList.Create;

//è? 1? ?? ?t ′? ?ú

if FileExists(Filename) then

begin

FList.LoadFromFile(FileName);

//2? è? ?? DD £? ?a ?ì ?÷ ìá 1? ±ê ê?

if FList.Strings[FList.Count - 1] <> &#39;&#39; then FList.Add(&#39;&#39;);

end;

end;

//?a ?? ′ú ?? ?¨ ò? á? ?á è? ×? ·? ′? μ? 1y 3ì

function TExtIniFile.ReadString(const Section: string; Ident: string; Default: string):

string;

var

ExtIni_I, ExtIni_Start, ExtIni_End, BufSize: Integer;

Section_Str, Ident_Str: string;

//TempList:TStringList;

Buffer, Pchar_Temp: Pchar;

IdentLen : Integer;

FindEndOK : Boolean;

begin

//è? 1? ?? ?t ′? ?ú

if FileExists(FFileName) then

begin

FindEndOK := False;

ExtIni_Start := -1;

ExtIni_End := -1;

IdentLen := Length(Ident);

//?ì ?÷ è? ?? £? 2é ?ò Section

for ExtIni_I := 0 to FList.Count - 1 do

begin

if UpperCase(FList.Strings[ExtIni_I]) = &#39;[&#39; + UpperCase(Section) + &#39;]&#39; then

begin

if ExtIni_Start = -1 then

begin

ExtIni_Start := ExtIni_I;

end;

end;

end;

//è? 1? 2é ?ò Section3é 1| ifExtIni_Start>-1thenbeginForExtIni_I:=ExtIni_Start+1toFList.Count-1dobeginBufSize:=Length(FList.Strings[ExtIni_I]);GetMem(Buffer,BufSize+2);Buffer^:=chr(0);

//?? è? μú ò? ?? ×? ·? strLcat(Buffer,PChar(FList.Strings[ExtIni_I]),1);

//è? 1? μú ò? ?? ×? ·? ?a &#39;[&#39;IfBuffer=&#39;[&#39;thenFindEndOK:=True;

//?ò ?a ?? ?μ ifFList.Strings[ExtIni_I]=&#39;&#39;thenFindEndOK:=True;

//±ê ?? ?? ?? μ? ?á ê? DD ifFindEndOK=Truethenbeginif Ext Ini-End=-1thenbeginExtIni_End:=ExtIni_I;end;end;

//êí ·? ?ú ′? FreeMem(Buffer);end;

//?ì ?÷ ?ü ForExtIni_I:=0toExtIni_End-1dobeginBufSize:=Length(FList.Strings[ExtIni_I]);GetMem(Buffer,BufSize+2);Buffer^:=chr(0);strLcat(Buffer,PChar(FList.Strings[ExtIni_I]),IdentLen+1);

//è? 1? ?ì ?÷ 3é 1| ifUpperCase(String(Buffer))=UpperCase(Ident+&#39;=&#39;)thenbegin

//?? ?D ×? ·? ′? BufSize:=Length(FList.Strings[ExtIni_I]);GetMem(Pchar_Temp,BufSize+2);Pchar_Temp^:=chr(0);StrCat(Pchar_Temp,PChar(FList.Strings[ExtIni_I])+Length(Ident)+1);Str_Temp:=String(Pchar_Temp);

//êí ·? FreeMem(Pchar_Temp);end;FreeMem(Buffer);end;end;end;

SetString(Result, pchar(Str_Temp), Length(Str_Temp));

if trim(Str_Temp) = &#39;&#39; then

Result := Default;

end;

//?a ?? ′ú ?? ?¨ ò? á? ?á è? êy ?μ μ? 1y 3ì

end;

function TExtIniFile.ReadInteger(const Section: string; Ident: string; Default: Longint):

Longint;

var

IntStr : string;

begin

try

IntStr := ReadString(Section, Ident, &#39;&#39;);

if (Length(IntStr) > 2) and (IntStr[1] = &#39;0&#39;) and ((IntStr[2] = &#39;X&#39;) or (IntStr[2] =

&#39;x&#39;)) then

IntStr := &#39;$&#39; + Copy(IntStr, 3, Maxint); Result := StrToIntDef(IntStr, Default);

finally

Result := StrToIntDef(IntStr, Default);

end;

end;

//?a ?? ′ú ?? ?¨ ò? á? ?á è? 2? ?? ?μ μ? 1y 3ì

function TExtIniFile.ReadBoolean(const Section: string; Ident: string; Default:

Boolean): Boolean;

begin

if Trim(ReadString(Section, Ident, &#39;A &#39;)) = &#39;1&#39; then

Result := true

else

Result :=

false; if (Str_Temp <> &#39;0 &#39;) and (Str_Temp <> &#39;1&#39;) then Result := Default;

end;

//?a ?? ′ú ?? ?¨ ò? á? ?ì ?÷ è? 2? ?? μ? ?? 3? μ? 1y 3ì

procedure TExtIniFile.ReadSections(Strings: TStrings);

//varExtIni_I,BufSize:Integer;Buffer,Pchar_Temp,Pchar_Temp2,Pchar_Temp3:Pchar;FindEndOK:Boolean;

begin

//è? 1? ?? ?t ′? ?ú ifFileExists(FFileName)thenbeginForExtIni_I:=0toFList.Count-1dobeginBufSize:=Length(FList.Strings[ExtIni_I])+2;GetMem(Buffer,BufSize);Buffer^:=chr(0);

//?? è? μú ò? ?? ×? ·? strLcat(Buffer,PChar(FList.Strings[ExtIni_I]),1);

//è? 1? μú ò? ?? ×? ·? ?a &#39;[&#39;IfBuffer=&#39;[?ˉ thenbegin//?ò 2é ?ò &#39;]&#39;GetMem(Pchar_Temp,BufSize);Pchar_Temp^:=chr(0);StrCat(Pchar_Temp,PChar(FList.Strings[ExtIni_I])+Length(FList.Strings[ExtIni_I])-1);ifPchar_Temp=&#39;]&#39;thenbeginGetMem(Pchar_Temp2,BufSize);Pchar_Temp2^:=chr(0);StrCat(Pchar_Temp2,PChar(FList.Strings[ExtIni_I])+1);GetMem(Pchar_Temp3,BufSize);Pchar_Temp3^:=chr(0);strLcat(Pchar_Temp3,Pchar_Temp2,Length(Pchar_Temp2)-1);

//?ú áD ±í ?D ?ó è? ×? ·? ′? Strings.Add(Pchar_Temp3);FreeMem(Pchar_Temp2);FreeMem(Pchar_Temp3);end;FreeMem(Pchar_Temp);end;FreeMem(Buffer);end;end;

end;

//?a ?? ′ú ?? ?¨ ò? á? ?ì ?÷ ?? ?¨ ?? ?ú μ? ?ü μ? ?? 3? μ? 1y 3ì

procedure TExtIniFile.ReadIdents(const Section: string; Strings: TStrings);

var

ExtIni_I, ExtIni_Start, ExtIni_End, BufSize: Integer; Section_Str, Ident_Str:

string; TempList : TStringList; Buffer, Pchar_Temp: Pchar; IdentLen: Integer; FindEndOK :

Boolean;

begin

//è? 1? ?? ?t ′? ?ú ifFileExists(FFileName)thenbeginFindEndOK:=False;ExtIni_Start:=-1;ExtIni_End:=-1;

//?ì ?÷ è? ?? £? 2é ?ò SectionForExtIni_I:=0toFList.Count-1dobeginifUpperCase(FList.Strings[ExtIni_I])=&#39;[&#39;+UpperCase(Section)+&#39;]&#39;thenbeginifExtIni_Start=-1thenExtIni_Start:=ExtIni_I;end;end;

//è? 1? 2é ?ò Section3é 1| ifExtIni_Start>-1thenbeginForExtIni_I:=ExtIni_Start+1toFList.Count-1dobeginBufSize:=Length(FList.Strings[ExtIni_I]);GetMem(Buffer,BufSize+2);Buffer^:=chr(0);

//?? è? μú ò? ?? ×? ·? strLcat(Buffer,PChar(FList.Strings[ExtIni_I]),1);

//è? 1? μú ò? ?? ×? ·? ?a &#39;[&#39;IfBuffer=&#39;[&#39;thenFindEndOK:=True;

//?ò ?a ?? ?μ ifFList.Strings[ExtIni_I]=&#39;&#39;thenFindEndOK:=True;

//±ê ?? ?? ?? μ? ?á ê? DD ifFindEndOK=TruethenbeginifExtIni_End=-1thenbeginExtIni_End:=ExtIni_I;end;end;

//êí ·? ?ú ′? FreeMem(Buffer);end;end;ForExtIni_I:=ExtIni_Start+1toExtIni_End-1dobegin

//2é ?ò &#39;=&#39;IdentLen:=pos(&#39;=&#39;,FList.Strings[ExtIni_I]);ifIdentLen<>0thenbeginBufSize:=Length(FList.Strings[ExtIni_I]);GetMem(Buffer,BufSize+2);Buffer^:=chr(0);

//?? è? ×? ·? strLcat(Buffer,PChar(FList.Strings[ExtIni_I]),IdentLen-1);Strings.Add(Buffer);freemem(Buffer);end;end;end;

end;

//?a ?? ′ú ?? ?¨ ò? á? D′ è? ×? ·? ′? μ? 1y 3ì

procedure TExtIniFile.WriteString(const Section: string; Ident: string; Value:

string);

var

ExtIni_I, ExtIni_Start, ExtIni_End, BufSize: Integer; Buffer: Pchar; IdentLen:

Integer; FindEndOK, FindOK: Boolean;

begin

FindEndOK := False;

FindOK := False;

ExtIni_Start := -1;

ExtIni_End := -1;

IdentLen := Length(Ident);

//è? 1? áD ±í °ü o? ?ú èY

if FList.Count > 0 then

begin

//?ì ?÷ è? ?? £? 2é ?ò Section

for ExtIni_I := 0 to FList.Count - 1 do

begin

if UpperCase(FList.Strings[ExtIni_I]) = &#39;[&#39; + UpperCase(Section) + &#39;]&#39; then

begin

if ExtIni_Start = -1 then

begin

ExtIni_Start := ExtIni_I;

end;

end;

end;

//è? 1? 2é ?ò Section ê§ °ü

if ExtIni_Start = -1 then

begin

FList.Add(&#39;[&#39; + Section + &#39;]&#39;);

ExtIni_Start := FList.Count - 1;

end;

//è? 1? 2é ?ò Section 3é 1|

if ExtIni_Start > -1 then

begin

for ExtIni_I := ExtIni_Start + 1 to FList.Count - 1 do

begin

BufSize := Length(FList.Strings[ExtIni_I]);

GetMem(Buffer, BufSize + 2);

Buffer^ := chr(0);

//?? è? μú ò? ?? ×? ·?

strLcat(Buffer, PChar(FList.Strings[ExtIni_I]), 1);

//è? 1? μú ò? ?? ×? ·? ?a &#39;[&#39;

if Buffer = &#39;[&#39; then FindEndOK := True;

//?ò ?a ?? ?μ

if FList.Strings[ExtIni_I] = &#39;&#39; then FindEndOK := True;

//±ê ?? ?? ?? μ? ?á ê? DD

if FindEndOK = True then

begin

if ExtIni_End = -1 then

begin

ExtIni_End := ExtIni_I;

end;

end;

//êí ·? ?ú ′?

FreeMem(Buffer);

end;

end;

//è? 1? ?? óD ?ò μ? ?? μ? ?á ê? DD

if ExtIni_End = -1 then

FList.Add(Ident + &#39; = &#39; + Value);

//è? 1? ?ò μ? ?? μ? ?á ê? DD

if ExtIni_End <> -1 then

begin

//?ì ?÷ ?ü

for ExtIni_I := ExtIni_Start + 1 to ExtIni_End do

begin

BufSize := Length(FList.Strings[ExtIni_I]);

GetMem(Buffer, BufSize + 2);

Buffer^ := chr(0);

StrLcat(Buffer, PChar(FList.Strings[ExtIni_I]),

IdentLen + 1);

//è? 1? ?ì ?÷ 3é 1|

if UpperCase(string(Buffer)) = UpperCase(Ident + &#39; = &#39;) then

begin

FList.Strings[ExtIni_I] := Ident + &#39; = &#39; + Value;

FindOK := True;

end;

FreeMem(Buffer, BufSize);

end;

if FindOK = false then

FList.Insert(ExtIni_End, Ident + &#39; = &#39; + Value);

end;

end;

if FList.Count = 0 then

begin

FList.Add(&#39;[&#39; + Section + &#39;]&#39;);

FList.Add(Ident + &#39; = &#39; + Value);

end;

FList.SaveToFile(FFileName);

end;

procedure TExtIniFile.WriteInteger(const Section:

string; Ident: string; Value: Integer);

begin

WriteString(Section, Ident, inttostr(Value));

end;

procedure TExtIniFile.WriteBoolean(const Section:

string; Ident: string; Value: Boolean);

begin

if Value = true then

WriteString(Section, Ident, &#39;1 &#39;)

else

WriteString(Section, Ident, &#39; 0&#39;);

end;

end.
  完成输入后,即完成了一个叫Extinifiles的非可视组件,安装到Delphi中,即可像操作inifiles一样操作Extinifiles,不仅操作方式兼容,生成的文件也相互兼容,不同之处是Extinifiles可以支持无限大的ini文件,可以使用到任何程序中。当然也可以将他改装并编译为一个Dll文件,便可以由VB调用了。在实际使用过程中,在赛阳300A的系统下可以非常快速的操作0M~1.5M的数据,而K6-2-300的系统则可以快速的操作0M~3M的数据。

  以上组件在Delphi3+中文Windows98中调试通过,经实验证明同样兼容Delphi5。这个组件和演示程序亦可通过访问http://qingyuan.csw.cnshare.net获得。(长沙 夏昆冈)

TOP

提示: 作者被禁止或删除 内容自动屏蔽

TOP

发新话题