TIniFile.WriteBinaryStream создает исключение
В 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) Доступны дополнительные данные.
Почему? Что это значит? Как решить эту проблему?
РЕДАКТИРОВАТЬ: с учетом того, что сказали @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;
1 ответ
Я считаю, что это ограничение функций операционной системы для обработки файлов INI; строка слишком длинная для этого.
Если вместо этого вы используете реализацию файла INI Delphi, TMemIniFile
, он отлично работает. Только не забудь позвонитьMyIni.UpdateFile
в конце.
Да, это действительно ограничение 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;
(Напомним, что файлы INI изначально использовались для хранения небольших объемов данных конфигурации в 16-битную эпоху Windows.)
Кроме того, Uwe Raabe прав: вы должны сохранить строку Base64 как текст.