You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi中Ini.ReadString无法识别带引号字符串,如何读取时修正?

解决Delphi INI读取时无法识别值带引号的问题

Delphi内置的TIniFile.ReadString()或TMemIniFile.ReadString()会自动去除值首尾的单/双引号,导致无法区分Database=MyName和Database='MyName'两种配置的差异。要解决这个问题,需要绕过内置方法的引号处理逻辑,直接读取原始配置值。

方案1:自定义INI读取函数(直接解析文件)

如果不需要依赖Delphi的INI类,可以自己实现一个简单的读取函数,直接解析INI文件的原始内容,保留值的原始格式:

function ReadIniRawString(const FileName, Section, Key, Default: string): string;
var
  SL: TStringList;
  I, SectionIdx: Integer;
  Line: string;
  KeyPrefix: string;
begin
  Result := Default;
  SL := TStringList.Create;
  try
    SL.LoadFromFile(FileName);
    // 定位目标Section
    SectionIdx := -1;
    for I := 0 to SL.Count - 1 do
    begin
      Line := Trim(SL[I]);
      // 跳过注释和空行
      if (Line = '') or (Line[1] = ';') then Continue;
      // 匹配Section
      if (Line[1] = '[') and (Line[Length(Line)] = ']') then
      begin
        if CompareText(Copy(Line, 2, Length(Line)-2), Section) = 0 then
        begin
          SectionIdx := I + 1;
          Break;
        end;
      end;
    end;
    if SectionIdx = -1 then Exit;
    // 在Section内查找目标Key
    KeyPrefix := Key + '=';
    for I := SectionIdx to SL.Count - 1 do
    begin
      Line := SL[I];
      // 遇到新Section则停止
      if (Trim(Line) <> '') and (Trim(Line)[1] = '[') then Break;
      // 跳过注释行
      if (Line <> '') and (Line[1] = ';') then Continue;
      // 匹配Key
      if Pos(KeyPrefix, TrimLeft(Line)) = 1 then
      begin
        // 提取等号后的原始内容(保留空格、引号)
        Result := Copy(Line, Pos('=', Line) + 1, MaxInt);
        Exit;
      end;
    end;
  finally
    SL.Free;
  end;
end;

使用示例:

var 
  aDatabase: string;
begin
  // 读取Ini文件#1,返回MyName
  aDatabase := ReadIniRawString('config1.ini', 'SectionDatabase', 'Database', 'error');
  // 读取Ini文件#2,返回'MyName'
  aDatabase := ReadIniRawString('config2.ini', 'SectionDatabase', 'Database', 'error');
end;

方案2:扩展TMemIniFile类(内存级解析)

如果已经在使用TMemIniFile,可以扩展该类,添加一个不处理引号的读取方法:

type
  TMyMemIniFile = class(TMemIniFile)
  public
    function ReadRawString(const Section, Ident, Default: string): string;
  end;

function TMyMemIniFile.ReadRawString(const Section, Ident, Default: string): string;
var
  SL: TStringList;
  I: Integer;
  Line: string;
  KeyPrefix: string;
begin
  Result := Default;
  // 获取目标Section的字符串列表
  SL := Sections.Values[Section];
  if not Assigned(SL) then Exit;
  
  KeyPrefix := Ident + '=';
  for I := 0 to SL.Count - 1 do
  begin
    Line := SL[I];
    // 匹配Key(忽略开头空格)
    if Pos(KeyPrefix, TrimLeft(Line)) = 1 then
    begin
      // 提取原始值,保留引号
      Result := Copy(Line, Pos('=', Line) + 1, MaxInt);
      Exit;
    end;
  end;
end;

使用示例:

var 
  Ini: TMyMemIniFile;
  aDatabase: string;
begin
  Ini := TMyMemIniFile.Create('config.ini');
  try
    // 读取原始值,保留引号
    aDatabase := Ini.ReadRawString('SectionDatabase', 'Database', 'error');
  finally
    Ini.Free;
  end;
end;

注意事项

  • 自定义解析逻辑需要考虑INI文件的常见格式细节:注释行(;开头)、空行、Key的大小写不敏感性(示例中用CompareText实现)。
  • 如果INI值包含多行内容(通过续行符\),需要额外处理续行逻辑,示例代码仅针对单行值场景。

内容的提问来源于stack exchange,提问作者Franz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 14:07:38