Преобразование AnsiString к строке Unicode

Я преобразовываю программу D2006 в D2010. Мне сохранили значение в единственном байте на символьную строку в моей базе данных, и я должен загрузить его в управление, которое имеет LoadFromStream, таким образом, мой план состоял в том, чтобы записать строку в поток и использование это с LoadFromStream. Но это не работало. В изучении проблемы я вижу проблему, которая говорит мне, что я действительно не понимаю, как преобразование от AnsiString до Unicode представляет работы в виде строки. Вот часть автономного кода, который иллюстрирует проблему, которой я смущен:;

procedure TForm1.Button1Click(Sender: TObject); {$O-}
var
  sBuffer: String;
  oStringStream: TStringStream;
  sAnsiString: AnsiString;
  sUnicodeString: String;
  iSize1,
  iSize2: Word;
begin
  sAnsiString := '12345';
  oStringStream := TStringStream.Create(sBuffer);
  sUnicodeString := sAnsiString;
  iSize1 := StringElementSize(sAnsiString);
  iSize2 := StringElementSize(sUnicodeString);
  oStringStream.WriteString(sUnicodeString);
end;

Если Вы повредитесь на последней строке и осмотрите свойство Bytes oStringStream, то Вы будете видеть, что это похоже на это:

Bytes (49 {$31}, 50 {$32}, 51 {$33}, 52 {$34}, 53 {$35}

Я ожидал, что это могло бы посмотреть что-то как

(49 {$31}, 00 {$00}, 50 {$32}, 00 {$00}, 51 {$33}, 00 {$00}, 
 52 {$34}, 00 {$00}, 53 {$35}, 00 {$00} ...

По-видимому, мои ожидания по ошибке. Но затем, как преобразовать AnsiString в unicode?

Я не вытаскиваю правильные результаты из LoadFromStream, потому что он читает из потока два байта за один раз, но данные, которые он получает, не расположены тот путь. Что я должен сделать, чтобы дать LoadFromStream хорошо сформированный поток данных на основе строки unicode?

Спасибо за помощь.

5
задан Pierre-Jean Coudert 1 April 2010 в 18:30
поделиться

3 ответа

Каков тип параметра oStringStream.WriteString? Если это AnsiString, у вас есть неявное преобразование из Unicode в Ansi, и это объясняет ваш пример.


Обновлено: теперь реальный вопрос заключается в том, как TStringStream хранит данные внутри. В следующем примере кода (Delphi 2009)

procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
  SS: TStringStream;

begin
  S:= 'asdfg';
  SS:= TStringStream.Create(S);  // 1 byte per char
  SS.WriteString('321');
  Label1.Caption:= SS.DataString;
  SS.Free;
end;

TStringStream использует внутреннюю системную кодировку ANSI по умолчанию (1 байт на символ). {{ 1}} Конструктор и процедуры WriteString преобразуют строковый аргумент из Unicode в ANSI.

Чтобы переопределить это поведение, вы должны явно объявить кодировку в конструкторе:

procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
  SS: TStringStream;

begin
  S:= 'asdfg';
  SS:= TStringStream.Create(S, TEncoding.Unicode);  // 2 bytes per char
  SS.WriteString('321');
  Label1.Caption:= SS.DataString;
  SS.Free;
end;
5
ответ дан 14 December 2019 в 13:32
поделиться

Я думаю, вы хотите использовать:

LoadFromStream(stream, TEncoding.ASCII);

Если ваш однобайтовый текст не ASCII, а основан на кодовой странице, то может подойти следующее:

LoadFromStream(stream, TEncoding.GetEncoding(1252));

где "1252" - кодовая страница, на которой основан ваш однобайтовый текст.

0
ответ дан 14 December 2019 в 13:32
поделиться

Формат потока в значительной степени зависит от TStringStream.Encoding. В вашем примере используемая кодовая страница должна быть такой же, как и sBuffer (см. импликацию из TStringStream.Create).

Поскольку oStringStream.WriteString(sUnicodeStream);, похоже, сохраняет как отдельные байты, я бы предположил, что sBuffer - это Ansistring или RawByteString.

Теперь... почему происходят сбои при чтении... Вы так и не привели пример того, как вы выполняете обратное чтение в этом потоке.

0
ответ дан 14 December 2019 в 13:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: