如何合并来自两个 TINIfile 实例的条目?
How to merge entries from two TINIfile instances?
有没有办法将条目从一个 TIniFile 实例合并到另一个实例?
没有单一的方法可以做到这一点。你可以这样自己做:
- 加载INI文件,暂且称它们为A和B。
- 枚举 B 中的部分。
- 对于 B 中的每个部分,枚举该部分中的 name/value 对。
- 将 B 中的每个 name/value 对添加到 A 中的相应部分。
- 完成后,保存文件 A,其中包含来自两个文件的条目。
枚举文件 A 的方法是 ReadSections
和 ReadSectionValues
。
您需要决定如何处理任何冲突。即出现在两个文件中的任何名称。
这是一个可以将两个 INI 文件合并到一个新的输出 INI 文件中的过程:
procedure MergeIniFiles(const FromFilename, ToFilename, OutputFilename: String;
const Overwrite: Boolean);
var
IniFrom, IniTo, IniOut: TIniFile;
Sec: TStringList;
Val: TStringList;
X, Y: Integer;
S, N, V: String;
begin
IniFrom:= TIniFile.Create(FromFilename);
IniTo:= TIniFile.Create(ToFilename);
IniOut:= TIniFile.Create(OutputFilename);
Sec:= TStringList.Create;
Val:= TStringList.Create;
try
IniFrom.ReadSections(Sec);
for X := 0 to Sec.Count-1 do begin
S:= Sec[X];
IniFrom.ReadSection(S, Val);
for Y := 0 to Val.Count-1 do begin
N:= Val[Y];
V:= IniFrom.ReadString(S, N, '');
IniOut.WriteString(S, N, V);
end;
end;
IniTo.ReadSections(Sec);
for X := 0 to Sec.Count-1 do begin
S:= Sec[X];
IniTo.ReadSection(S, Val);
for Y := 0 to Val.Count-1 do begin
N:= Val[Y];
V:= IniTo.ReadString(S, N, '');
if Overwrite then begin
IniOut.WriteString(S, N, V);
end else begin
if not IniOut.ValueExists(S, N) then
IniOut.WriteString(S, N, V);
end;
end;
end;
finally
Val.Free;
Sec.Free;
IniOut.Free;
IniTo.Free;
IniFrom.Free;
end;
end;
我想要实现的是在我的安装程序中有一个 ini 文件,它将与 'Program Files' 中的主要可执行文件一起放置。此 ini 将包含应用程序的许多属性的默认值。因此用户的实际 ini 文件(例如在主文件夹中)将从那里读取 "factory" 默认值。这种方法类似于 OSX 的 NSUserDefaults
。我认为在 某些情况下 这很有用,而不是仅仅使用 inifile.readString()
中的默认值。谢谢大家的回答,我只是 post 为此目的的最终功能...
procedure inifileLoadDefaults(const defaults: TFileName; destination:TIniFile);
var inif: TIniFile;
begin
inif := TIniFile.Create(defaults);
try
inifileLoadDefaults(inif, destination);
finally
inif.Free;
end;
end;
procedure inifileLoadDefaults(const defaults: TIniFile; destination:TIniFile);
var secs, secsVal: TStrings;
i, k: Integer;
begin
secs := TStringList.Create;
secsVal := TStringList.Create;
try
defaults.ReadSections(secs);
for i:=0 to secs.Count -1 do begin
defaults.ReadSection(secs[i], secsVal);
for k:=0 to secsVal.Count -1 do
if not(destination.ValueExists(secs[i], secsVal[k])) then
destination.WriteString(secs[i], secsVal[k], defaults.ReadString(secs[i], secsVal[k], ''));
end;
finally
secsVal.Free;
secs.Free;
end;
end;
有没有办法将条目从一个 TIniFile 实例合并到另一个实例?
没有单一的方法可以做到这一点。你可以这样自己做:
- 加载INI文件,暂且称它们为A和B。
- 枚举 B 中的部分。
- 对于 B 中的每个部分,枚举该部分中的 name/value 对。
- 将 B 中的每个 name/value 对添加到 A 中的相应部分。
- 完成后,保存文件 A,其中包含来自两个文件的条目。
枚举文件 A 的方法是 ReadSections
和 ReadSectionValues
。
您需要决定如何处理任何冲突。即出现在两个文件中的任何名称。
这是一个可以将两个 INI 文件合并到一个新的输出 INI 文件中的过程:
procedure MergeIniFiles(const FromFilename, ToFilename, OutputFilename: String;
const Overwrite: Boolean);
var
IniFrom, IniTo, IniOut: TIniFile;
Sec: TStringList;
Val: TStringList;
X, Y: Integer;
S, N, V: String;
begin
IniFrom:= TIniFile.Create(FromFilename);
IniTo:= TIniFile.Create(ToFilename);
IniOut:= TIniFile.Create(OutputFilename);
Sec:= TStringList.Create;
Val:= TStringList.Create;
try
IniFrom.ReadSections(Sec);
for X := 0 to Sec.Count-1 do begin
S:= Sec[X];
IniFrom.ReadSection(S, Val);
for Y := 0 to Val.Count-1 do begin
N:= Val[Y];
V:= IniFrom.ReadString(S, N, '');
IniOut.WriteString(S, N, V);
end;
end;
IniTo.ReadSections(Sec);
for X := 0 to Sec.Count-1 do begin
S:= Sec[X];
IniTo.ReadSection(S, Val);
for Y := 0 to Val.Count-1 do begin
N:= Val[Y];
V:= IniTo.ReadString(S, N, '');
if Overwrite then begin
IniOut.WriteString(S, N, V);
end else begin
if not IniOut.ValueExists(S, N) then
IniOut.WriteString(S, N, V);
end;
end;
end;
finally
Val.Free;
Sec.Free;
IniOut.Free;
IniTo.Free;
IniFrom.Free;
end;
end;
我想要实现的是在我的安装程序中有一个 ini 文件,它将与 'Program Files' 中的主要可执行文件一起放置。此 ini 将包含应用程序的许多属性的默认值。因此用户的实际 ini 文件(例如在主文件夹中)将从那里读取 "factory" 默认值。这种方法类似于 OSX 的 NSUserDefaults
。我认为在 某些情况下 这很有用,而不是仅仅使用 inifile.readString()
中的默认值。谢谢大家的回答,我只是 post 为此目的的最终功能...
procedure inifileLoadDefaults(const defaults: TFileName; destination:TIniFile);
var inif: TIniFile;
begin
inif := TIniFile.Create(defaults);
try
inifileLoadDefaults(inif, destination);
finally
inif.Free;
end;
end;
procedure inifileLoadDefaults(const defaults: TIniFile; destination:TIniFile);
var secs, secsVal: TStrings;
i, k: Integer;
begin
secs := TStringList.Create;
secsVal := TStringList.Create;
try
defaults.ReadSections(secs);
for i:=0 to secs.Count -1 do begin
defaults.ReadSection(secs[i], secsVal);
for k:=0 to secsVal.Count -1 do
if not(destination.ValueExists(secs[i], secsVal[k])) then
destination.WriteString(secs[i], secsVal[k], defaults.ReadString(secs[i], secsVal[k], ''));
end;
finally
secsVal.Free;
secs.Free;
end;
end;