【问题标题】:How to merge entries from two TINIfile instances?如何合并来自两个 TINIfile 实例的条目?
【发布时间】:2016-03-19 06:02:26
【问题描述】:

有没有办法将条目从一个 TIniFile 实例合并到另一个?

【问题讨论】:

  • 不直接,不。您必须从一个TIniFile 读取值,并根据需要将它们写入另一个TIniFile。如果您在执行此操作时遇到问题,请出示您的实际代码。

标签: delphi delphi-7 ini


【解决方案1】:

我想要实现的是在我的安装程序中有一个 ini 文件,该文件将与“程序文件”中的主要可执行文件一起放置。此 ini 将包含应用程序许多属性的默认值。因此,用户的实际 ini 文件(例如在主文件夹中)将从那里读取“工厂”默认值。这种方法类似于 OSX 的NSUserDefaults。我认为在某些情况下这很有用,而不是仅仅使用inifile.readString() 中的默认值。谢谢大家的回答,我只是为了这个目的发布最终功能......

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;

【讨论】:

    【解决方案2】:

    这是一个可以将两个 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;
    

    【讨论】:

    • 感谢您的实施,我将不得不更改以使用 TINIFile 参数。
    • @VassilisGr 确实,我只是在猜测意图是什么。由您决定如何适应现有值。
    【解决方案3】:

    没有单一的方法可以做到这一点。你可以这样自己做:

    1. 加载INI文件,我们称它们为A和B。
    2. 枚举B中的部分。
    3. 对于 B 中的每个部分,枚举该部分中的名称/值对。
    4. 将 B 中的每个名称/值对添加到 A 中的相应部分。
    5. 完成后,保存文件 A,其中包含两个文件中的条目。

    您将用于枚举文件 A 的方法是 ReadSectionsReadSectionValues

    您需要决定如何处理任何冲突。那是出现在两个文件中的任何名称。

    【讨论】:

    • "你需要决定"确实,+ 1
    • ReadSectionValues +1。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多