下面是相關源碼:
1.實現任意多位元組語言與Unicode的轉換:
function UnicodeEncode(Str: string; CodePage: integer): WideString;
var
Len: integer;
begin
Len := Length(Str) + 1;
SetLength(Result, Len);
Len := MultiByteToWideChar(CodePage, 0, PChar(Str), -1, PWideChar(Result), Len);
SetLength(Result, Len - 1); //end is #0
end;
function UnicodeDecode(Str: WideString; CodePage: integer): string;
var
Len: integer;
begin
Len := Length(Str) * 2 + 1; //one for #0
SetLength(Result, Len);
Len := WideCharToMultiByte(CodePage, 0, PWideChar(Str), -1, PChar(Result), Len, nil, nil);
SetLength(Result, Len - 1);
end;
比如,GB2312的字碼頁是936,則GB2312要轉為Unicode可以這樣:
UniStr := UnicodeEncode(GBStr, 936);
要從Unicode內碼轉為GB2312則可以這樣:
GBStr := UnicodeDecode(UniStr, 936);
對於其他語言也是一樣,只要知道了字碼頁。
注:日文的字碼頁是932
2.檔案的編碼變換
首先看這位大俠的幾個提示:
AnsiToUTF8
UTF8ToUnicode
看一下這兩個函數的協助。
你可以用一個TStringList將文字檔Load進來,然後聲明一個WideString變數,最後調用上面的StringToWideChar,轉換後的資訊儲存在WideString中。
再聲明一個MemoryStream將WideString寫進流中。
最後將流儲存為一個文字檔。
你去檔案檔案看,它就是Unicode編碼的,且資訊一樣。
下面是終極版:
每一種格式的文本在最開頭都會有一個標識,標識它是什麼編碼。比如Unicode的最開頭就是FFFE。筆記本就 是根據最開頭的這個標識來識別它是什麼碼的。
而你在上面寫的時候,沒有將這個標識寫在檔案的最開頭,所以你用筆記本開啟的時候識別不了,不信你開啟之後選另存新檔,就可以看到它識別為Ansi碼了,所以會顯示不對。
正確的做法是在檔案的開頭寫進FFFE這個標識,就可以正確顯示了。
下面是源碼:
var SL: TStringList;
MM: TMemoryStream;
AnStr: String;
WS: WideString;
P: PByteArray;
begin
SL:= TStringList.Create;
MM:= TMemoryStream.Create;
try
SL.LoadFromFile('test.txt');
AnStr:= SL.Text;
WS:= AnStr; //轉為Unicode
//文本開頭寫進Unicode的標識
GetMem(P, 2 * Sizeof(Char));
P[0]:= $FF;
P[1]:= $FE;
MM.Write(P^, 2 * Sizeof(Char));
//將Unicode文本寫進流中儲存。
MM.Write(PWideChar(WS)^, Length(WS) * Sizeof(WideChar));
MM.SaveToFile('test2.txt');
FreeMem(P);
finally
SL.Free;
MM.Free;
end;
end;
我先在一個筆記本中寫下:“yes是的,這是Unicode”,然後儲存為Test檔案。這個時候它是Ansi編碼。
執行我上面的代碼之後,文本儲存為Test2,這時它就是Unicode碼了,可以正確顯示,你可選另存新檔看看它是不是Unicode編碼。
然後還有另外一個哥們的發言:
warmworm(warmworm)
厚厚
以前我也為ansi和unicode的轉換,看遍了這些函數,其實最簡單的方法
就是
Ansi->Unicode
strUnicode := WideString(strAnsi);
Unicode->Ansi
strAnsi := AnsiString(strUnicode);
另一個文章中:
aiirii(ari-http://spaces.msn.com/members/aiirii/)
unicode文字檔:頭兩個字元分別是FF FE(16進位)
unicode big endian文字檔:頭兩個字元分別是FE FF(16進位,big endian自然會是相反的)
utf-8文字檔:頭兩個字元分別是EF BB(16進位) (補充:如果想通過寫入檔案頭來標識utf-8編碼檔案,則需要寫入Write(LogFile,#$EF#$BB#$BF);)
可以用記事本開啟一個文字檔,以各種方式另存新檔,再用16進位編輯器就可以看到了。