TIniFile.WriteBinaryStream 创建异常

TIniFile.WriteBinaryStream creates exception

在 Delphi 10.4 中,我尝试将有效的 TPicture base64 编码保存到 INI 文件中:

procedure TForm1.SavePictureToIniFile(const APicture: TPicture);
var
  LInput: TMemoryStream;
  LOutput: TMemoryStream;
  MyIni: TIniFile;
  ThisFile: string;
begin
  if FileSaveDialog1.Execute then
    ThisFile := FileSaveDialog1.FileName
  else EXIT;

  LInput := TMemoryStream.Create;
  LOutput := TMemoryStream.Create;
  try
    APicture.SaveToStream(LInput);
    LInput.Position := 0;
    TNetEncoding.Base64.Encode(LInput, LOutput);
    LOutput.Position := 0;

    MyIni := TIniFile.Create(ThisFile);
    try
      MyIni.WriteBinaryStream('Custom', 'IMG', LOutput); // Exception# 234
    finally
      MyIni.Free;
    end;
  finally
    LInput.Free;
    LOutput.Free;
  end;
end;

WriteBinaryStream 创建异常:

ERROR_MORE_DATA 234 (0xEA) More data is available.

为什么?这是什么意思?如何解决这个问题?

编辑: 考虑到@Uwe Raabe 和@Andreas Rejbrand 所说的内容,此代码(不使用 base64 编码)现在有效:

procedure TForm1.SavePictureToIniFile(const APicture: TPicture);
var
  LInput: TMemoryStream;
  MyIni: System.IniFiles.TMemIniFile;
  ThisFile: string;
begin
  if FileSaveDialog1.Execute then
    ThisFile := FileSaveDialog1.FileName
  else EXIT;

  LInput := TMemoryStream.Create;
  try
    APicture.SaveToStream(LInput);
    LInput.Position := 0;

    MyIni := TMemIniFile.Create(ThisFile);
    try
      MyIni.WriteBinaryStream('Custom', 'IMG', LInput);
      MyIni.UpdateFile;
    finally
      MyIni.Free;
    end;
  finally
    LInput.Free;
  end;
end;

我认为这是操作系统处理 INI 文件功能的限制;字符串太长了。

如果您改为使用 Delphi INI 文件实现,TMemIniFile,它工作得很好。只是不要忘记在最后调用 MyIni.UpdateFile

是的,这确实是 the Windows API 中的限制,如以下最小示例所示:

var
  wini: TIniFile;
  dini: TMemIniFile;
begin

  wini := TIniFile.Create('C:\Users\Andreas Rejbrand\Desktop\winini.ini');
  try
    wini.WriteString('General', 'Text', StringOfChar('W', 10*1024*1024));
  finally
    wini.Free;
  end;

  dini := TMemIniFile.Create('C:\Users\Andreas Rejbrand\Desktop\pasini.ini');
  try
    dini.WriteString('General', 'Text', StringOfChar('D', 10*1024*1024));
    dini.UpdateFile;
  finally
    dini.Free;
  end;

(回想一下,在 16 位 Windows 时代,INI 文件最初用于存储少量配置数据。)

还有Uwe Raabe是对的:你应该将Base64字符串保存为文本。