Название статьи: Работа с tList<string> и tFileStream в Delphi: правильный подход к записи и чтению данных
Вопрос пользователя заключается в проблеме записи tList<string> в файл с использованием tFileStream в среде Delphi. Проблема возникает из-за неправильного понимания того, как работает запись данных в файл через TFileStream. В данном случае, при попытке записать строку из tList<string> в файл, происходит запись указателя на строку, а не самой строки, что приводит к ошибкам при чтении.
Описание проблемы
Пользователь использует операционную систему Windows 10 и среду разработки Berlin. При попытке сохранить tList<string> в файл с использованием tFileStream, возникают проблемы. Несмотря на знание работы с TStringList, TStreamWriter и TStreamReader, пользователь стремится использовать tFileStream, так как планируется добавление других типов данных в файл. В коде, при чтении данных из файла, возникает исключение eOutOfMemory, что указывает на проблему с записью данных. Пользователь отмечает, что при записи простых строковых значений всё работает корректно, но при попытке записать значение из tList, данные в файле оказываются неверными.
Подход к решению
Для корректной работы с tFileStream и tList<string> необходимо понимать, что метод Write в tFileStream ожидает буфер данных, а не строку напрямую. При работе со строками в Delphi, которые являются UnicodeString, необходимо учитывать, что каждый символ занимает 2 байта. Следовательно, при записи и чтении строк, нужно передавать количество байт, а не символов.
Пример корректной записи строки в файл
procedure TForm1.Button1Click(Sender: TObject);
var
_List: TList<string>;
_FileStream: TFileStream;
_String: string;
i, Length: Integer;
begin
_List := TList<string>.Create;
_List.Add('abcde');
_List.Add('abcde12345');
_FileStream := TFileStream.Create('test', fmCreate);
for i := 0 to _List.Count - 1 do
begin
_String := _List[i];
Length := Length(_String) * SizeOf(Char);
_FileStream.Write(Length, SizeOf(Integer));
_FileStream.Write(PChar(_String)^, Length);
end;
_FileStream.Free;
_List.Free;
end;
Пример корректного чтения строки из файла
procedure TForm1.Button2Click(Sender: TObject);
var
_FileStream: TFileStream;
_String: string;
Length: Integer;
i: Integer;
begin
_FileStream := TFileStream.Create('test', fmOpenRead);
while not _FileStream.Eof do
begin
_FileStream.Read(Length, SizeOf(Integer));
SetLength(_String, Length div SizeOf(Char));
_FileStream.Read(_String[1], Length);
Memo1.Lines.Add(_String);
end;
_FileStream.Free;
end;
Заключение
При работе с tList<string> и tFileStream важно понимать, что запись и чтение данных должно происходить в байтах, а не в символах. Также необходимо корректно обрабатывать длину строки и указатели на данные. Следуя этим рекомендациям, можно избежать ошибок, связанных с неправильной записью и чтением данных из файла.
Проблема заключается в некорректной записи и чтении данных из файла с использованием `tFileStream` и `tList` в Delphi из-за неправильного понимания обращения с указателями и байтами данных.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.