使用TiniFile类使用注释行编写INI文件

时间:2014-02-18 22:51:45

标签: delphi ini

我能否以任何方式使用Delphi中的 TIniFile 类来为我的INI文件写评论?

[VALUES]
; first number
a=5
; something else
b=25
...
...

在我在网上找到的示例(EXAMPLE)中,有时添加了很好的注释行,但没有显示如何创建,读取,写入这些行.......

5 个答案:

答案 0 :(得分:6)

TIniFile类是提供INI文件服务的Windows API函数的松散包装器。该API不支持编写注释,因此TIniFile也不能这样做。

如果要发出带注释的文件,则必须找到不同的INI文件库,或者自己滚动。

答案 1 :(得分:4)

TIniFileTMemIniFile都不支持读取或写入INI文件注释。

如果您需要添加或检索评论,则需要使用TStringList,并使用NamesValues功能来读取和写入值。您可以使用SaveToFile保存文件,并使用LoadFromFile加载该文件,但是自己处理默认值和各种ReadXX方法需要花费更多的工作。

答案 2 :(得分:1)

只能建议使用WriteString,如下所示:

ini.WriteString('VALUES','; first number','');

结果与您的预期不完全相同,但无论如何您都可以添加一些评论。

答案 3 :(得分:1)

实际上,您可以使用TIniFile:

WriteString('Section', '; Comment'#13#10 + 'Name', 'Value');

在这里检查该值不存在:

if ReadString('Section', 'Name', #13#10) = #13#10 then
  WriteString('Section', '; Comment'#13#10 + 'Name', 'Value');

(TIniFile具有ValueExists功能,但它会读取整个部分并搜索密钥。我更喜欢这种小检查。)

答案 4 :(得分:0)

我知道这是一个老问题,但我会添加我的功能来添加对ini文件的评论。随意改善。 抱歉语法错误。英语不是我的主要语言

class Procedure TCoreIniAsTextFile.AddComment(ini: TiniFile; Comment: array of string; Section: string = ''; Key: string = '');
Const
  LIST_NUMERIC_SIZE: Integer = 3;
var
  IniAsText         : Tstrings;
  i                 : Integer;
  j                 : Integer;
  Buffer            : string;
  // Method to remove previous comment
  Procedure WriteComment(StartLine: Integer);
var
  Linha             : Integer;
  LinBuf            : string;
begin
  repeat
    // add a space to avoid a except in the following line
    // if a line is blank
    LinBuf := Trim(IniAsText[StartLine]) + ' ';
    if LinBuf[1] = ';' then // is a comment
      IniAsText.Delete(StartLine);
  until (LinBuf[1] <> ';') or (IniAsText.Count = 0);
  // add new comment
  for Linha := High(Comment) downto Low(Comment) do
    begin
      IniAsText.Insert(StartLine, ';' + Comment[Linha]);
    end;

  IniAsText.Insert(StartLine, ''); // add a line for esthetic purposes  
  IniAsText.SaveToFile(ini.FileName);
end;
// function to add zeros to left 1 -> 001
function StrZeroReg(num: Int64; nsize: Integer): string;
begin
  Result := IntToStr(num);
  Result := StringOfChar('0', nsize - Length(Result)) + Result;
end;  
begin
  IniAsText := nil; // to avoid a warning below
  Section := Uppercase(Section);
  Key := Uppercase(Key);
  try
    IniAsText := TStringList.Create;
    if not FileExists(ini.FileName) then
      IniAsText.SaveToFile(ini.FileName);  // Create a blank file 

    IniAsText.LoadFromFile(ini.FileName);

    // If no section or key direct comment to file header
    if (Section = EmptyStr) and (Key = EmptyStr) then
      begin
        WriteComment(0);
        Exit;
      end;

    // If key is passed section is required 
    if (Section = EmptyStr) and (Key <> EmptyStr) then
      begin
        if not ini.SectionExists(Section) then
          raise Exception.Create('Section is required to write key comment');
      end;

    //If section is passed, but not key assume coment is to section 
    if (Section <> EmptyStr) and (Key = EmptyStr) then
      begin
        // section must exists
        if not ini.SectionExists(Section) then
          raise Exception.Create('Section ' + Section + ' does not exists');

        // search for section location in file 
        for i := 0 to IniAsText.Count - 1 do
          begin
            Buffer := Trim(Uppercase(IniAsText[i]));
            if (Buffer = '[' + Section + ']') then
              begin
                WriteComment(i);
                Exit;
              end;
          end;

        // sanity check
        raise Exception.Create('Section ' + Section + ' does not exists');
        exit;
      end;

    // If key and section is passed assume is a key comment
    if not ini.ValueExists(Section, Key) then
      begin

        // some ini libraries save stringlists to ini and save values as
        // valuea001,valuea002,...,valueannn . then search KEY000 as compatibility
        if ini.ValueExists(Section, Key + StrZeroReg(0, LIST_NUMERIC_PALCES)) then
          Key := Key + StrZeroReg(0, LIST_NUMERIC_PALCES)
        else // if not found Key000
          raise Exception.Create('KEY ' + Section + '\' + Key + ' does not exists');
      end;

    // search combination of section + key 
    for i := 0 to IniAsText.Count - 1 do
      begin
        Buffer := Trim(Uppercase(IniAsText[i]));
        if (Buffer = '[' + Section + ']') then
          begin
            for j := i + 1 to IniAsText.Count - 1 do
              begin
                Buffer := Trim(Uppercase(IniAsText[j])) + ' '; // space to avoid a exception 
                // Buffer[1] <> ';' to avoid commented lines 
                // Key + '=', Buffer) = 1 to avoid false cognats but will fail if param is 
                // param =value (valid to some libraries)
                if (Buffer[1] <> ';') and (Pos(Key + '=', Buffer) = 1) then
                  begin
                    WriteComment(j);
                    Exit;
                  end;
              end
          end;
      end;

  finally
    if Assigned(IniAsText) then
      IniAsText.Free;
  end;
end;