Delphi 2010 寫入UTF8檔案

Delphi 2010還沒完全Unicode化,但是在寫入UTF8檔案方面,和2007版又不太一樣。
Unicode編碼,基於文字檔的檔頭,有以下的檔頭編碼方式:

EF BB BF    UTF-8
FE FF     UTF-16/UCS-2, little endian
FF FE     UTF-16/UCS-2, big endian
FF FE 00 00   UTF-32/UCS-4, little endian.
00 00 FE FF   UTF-32/UCS-4, big-endian.


Delphi 2010中,有UTF8String型別,看宣告中即是:

UTF8String = type AnsiString(65001);

在Windows 平台上,65001 code page指的就是UTF8

另外,Delphi 2010中,string內定是Widestring,以往都是和用字串,塞EF BB BF後,再寫進檔案,如:

s := #$EF + #$BB + #$BF;
Write(s[1], 3);

可是在Delphi 2010中,string s 其實是 EF 00 BB 00 BF 00的WideString,寫入後會失敗。
修改一般的作法後如下,目前看來是能正常寫入有BOM檔頭的UTF8文字檔:


var
  hb : array of byte;
  u8 : UTF8String;

begin
    with TMemoryStream.Create do

    try
      SetLength(hb, 3);
      hb[1] := $EF;
      hb[2] := $BB;
      hb[3] := $BF;
      Write(hb[1], 3);
      u8 := AnsiToUtf8(Memo2.Text);
      Write(u8[1], Length(u8));
      Position := 0;
      SaveToFile('d:\1.txt');
    finally
      Free;
    end;
end;

讀取UTF8(沒試過):
1. 先判別檔頭是否是 EF BB BF
2. 用UTF8ToAnsi轉回來

留言

Eden寫道…
你好,或許使用Stream來處理也不錯,請參考看看
Wrtiting string to TMemoryStream - Pointer to string
bbfox寫道…
經你說明,拜讀這解法了,Thanks!

這個網誌中的熱門文章

Google瀏覽器發生「錯誤107 (net::ERR_SSL_PROTOCOL_ERROR): SSL 通訊協定錯誤」的解決方式

Tomato Port Forwarding / Port Triggering 設定