Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Работа с `TMemoryStream` в Delphi: корректное чтение и запись строк Unicode

Delphi , Синтаксис , Память и Указатели

Работа с TMemoryStream в Delphi: корректное чтение и запись строк Unicode

В данной статье мы рассмотрим проблему, с которой сталкиваются разработчики при работе с TMemoryStream в Delphi, особенно при чтении и записи строк Unicode. Эта проблема часто выражается в том, что после чтения данных из TMemoryStream строки содержат случайные значения, а не ожидаемые данные. Мы постараемся объяснить причину возникновения этой ошибки и предложим корректное решение.

Проблема

Разработчики часто сталкиваются с трудностями при записи и последующем чтении строк из TMemoryStream в Delphi. Пример кода, представленный ниже, демонстрирует типичную ситуацию, когда перед сохранением данных в файл строка содержит ожидаемое значение, но после загрузки данных из файла строка оказывается некорректной.

procedure SaveData(FileName: TFileName);
var
     MemStr: TMemoryStream;
     Title: String;
begin
     MemStr:= TMemoryStream.Create;
     try
          MemStr.Seek(0, soFromBeginning);
          WriteStreamStr(MemStr, Title);
          MemStr.SaveToFile(FileName);
     finally
          MemStr.Free;
     end;
end;

procedure LoadData(FileName: TFileName);
var
     MemStr: TMemoryStream;
     Title: String;
begin
     MemStr:= TMemoryStream.Create;
     try
          MemStr.LoadFromFile(FileName);
          MemStr.Seek(0, soFromBeginning);
          Title := ReadStreamStr(MemStr);
     finally
          MemStr.Free;
     end;
end;

procedure WriteStreamStr(Stream: TStream; Str: string);
var
     StrLen: Integer;
begin
     StrLen := Length(Str);
     WriteStreamInt(Stream, StrLen);
     if StrLen > 0 then
          Stream.Write(Str[1], StrLen);
end;

function ReadStreamStr(Stream: TStream): string;
var
     LenStr: Integer;
begin
     Result := '';
     LenStr := ReadStreamInt(Stream);
     SetLength(Result, LenStr);
     Stream.Read(Result[1], LenStr);
end;

Описание проблемы с Unicode

Проблема, которая возникает, связана с тем, как в Delphi представляются строки Unicode. В коде, представленном выше, используется Stream.Write для записи строки в TMemoryStream, что делается на основе предположения, что каждый символ строки занимает один байт. Это верно для строк ANSI, но не для строк Unicode, где каждый символ занимает два байта (если рассматривать стандартный размер символа в Delphi, который SizeOf(Char) равен 2).

Решение

Исправление кода состоит в том, чтобы изменить количество байтов, передаваемых функции Stream.Write, на StrLen * SizeOf(Char). Это гарантирует, что будет записано корректное количество байтов для строки Unicode. Аналогично, при чтении данных из потока, необходимо использовать SizeOf(Char) для корректного чтения строки.

procedure WriteStreamStr(Stream: TStream; Str: string);
var
     StrLen: Integer;
begin
     StrLen := Length(Str);
     WriteStreamInt(Stream, StrLen);
     if StrLen > 0 then
          Stream.Write(Str[1], StrLen * SizeOf(Str[1]));
end;

function ReadStreamStr(Stream: TStream): string;
var
     LenStr: Integer;
begin
     Result := '';
     LenStr := ReadStreamInt(Stream);
     SetLength(Result, LenStr * SizeOf(Char)); // Учитываем размер символа
     Stream.Read(Result[1], LenStr * SizeOf(Char));
end;

Альтернативные подходы

Перед тем как применить исправления, стоит рассмотреть альтернативные подходы, такие как использование TStringStream или методов TStrings.SaveToStream и LoadFromStream. Это может быть более простым и эффективным решением, особенно если требуется работать только со строками.

Заключение

В данной статье мы рассмотрели типичную проблему, связанную с некорректной работой с TMemoryStream и строками Unicode в Delphi. Предложенное решение заключается в корректировке количества байтов, передаваемых при записи и чтении данных, с учетом размера символа в строке. Это позволит избежать ошибок при работе с Unicode-строками в TMemoryStream.

Создано по материалам из источника по ссылке.

Статья посвящена решению проблемы корректного чтения и записи строк Unicode с использованием `TMemoryStream` в Delphi, где рассмотрена ошибка, связанная с неправильным учетом размера символов Unicode при работе с потоками.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Память и Указатели ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-01 13:29:05/0.0032448768615723/0