簡體   English   中英

Delphi Unicode字符串長度,以字節為單位

[英]Delphi Unicode String Length in Bytes

我正在努力將一些Delphi 7代碼移植到XE4,因此,unicode就是這里的主題。

我有一個方法,其中一個字符串被寫入TMemoryStream,所以根據這篇embarcadero文章 ,我應該將字符串的長度(以字符為單位)乘以Char類型的大小,以獲得所需的字節長度。 WriteBuffer的長度(以字節為單位)參數。

所以之前:

rawHtml : string; //AnsiString
...
memorystream1.WriteBuffer(Pointer(rawHtml)^, Length(rawHtml);

后:

rawHtml : string; //UnicodeString
...
memorystream1.WriteBuffer(Pointer(rawHtml)^, Length(rawHtml)* SizeOf(Char));

我對Delphi的UnicodeString類型的理解是它內部是UTF-16。 但我對Unicode的一般理解是,即使是2個字節也不能表示所有unicode字符,有些角落外殼字符將占用4個字節。 embarcadero的另一篇文章似乎證實了我的懷疑,“事實上,一個Char等於兩個字節甚至不總是這樣!”

所以...這讓我想知道Length(rawHtml)* SizeOf(Char)是否真的足夠穩健以保持一致,或者是否有更好的方法來確定更准確的字符串大小?

Delphi的UnicodeString使用UTF-16編碼。 UTF-16是一種可變長度編碼,就像UTF-8一樣。 換句話說,單個Unicode代碼點可能需要多個字符元素來對其進行編碼。 作為一個興趣點,唯一的固定長度Unicode編碼是UTF-32。 UTF-16編碼使用16位字符元素,因此名稱。

在Unicode Delphi中, CharWideChar的別名,它是UTF-16字符元素。 stringUnicodeString的別名, UnicodeStringWideChar元素的數組。 Length()函數返回數組中的元素數。

因此,對於UnicodeStringSizeOf(Char)始終為2。 某些Unicode代碼點使用多個字符元素或Char來編碼。 Length()返回字符元素的數量而不是代碼點的數量。 字符元素都具有相同的大小。 所以

memorystream1.WriteBuffer(Pointer(rawHtml)^, Length(rawHtml)* SizeOf(Char));

是正確的。

我對Delphi的UnicodeString類型的理解是它內部是UTF-16。

你對Delphi的UnicodeString UTF-16編碼是正確的。 這意味着一個16位字符的寬度足以將基本多語言平面中的所有代碼點表示為string數組的一個Char元素。

但我對Unicode的一般理解是,即使是2個字節也不能表示所有unicode字符,有些角落外殼字符將占用4個字節。

但是,你在這里有一點誤解。 Length函數不會對字符執行任何深度檢查,只返回16位WideChar元素的數量,而不考慮字符串中的任何代理。 這意味着如果將任何補充平面中的單個字符分配給UnicodeString ,則Length將返回2。

program Egyptian;

{$APPTYPE CONSOLE}

var
  S: UnicodeString;

begin
  S := #$1304E;  // single char
  Writeln(Length(S));
  Readln;
end.

結論 :無論S包含任何可變長度字符,字符串數據的字節大小始終是固定的並且等於Length(S) * SizeOf(Char)

其他人已經解釋了如何編碼UnicodeString以及如何計算其字節長度。 我只想提一下RTL已經有了這樣的功能SysUtils.ByteLength()

memorystream1.WriteBuffer(PChar(rawHtml)^, ByteLength(rawHtml));

你正在做的是正確的(使用sizeof(Char))。

你所指的是,沒有一個字符指代一個代碼點(例如,由於代理對)。 但是字符串中的USC2編碼(非UTF-16)字符恰好占用了Length( Str ) * sizeof( Char )的字節數。

請注意,Delphi中使用的Unicode編碼與.... W變體中的所有Windows API調用相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM