String types like UnicodeString, AnsiString, WideString and UTF8String are stored in a memory using their respective encoding (see String Types for more details). Assigning one type of string into another may result in a conversion. Type string is designed to be encoding independent - you should never use its internal representation.
The class Sysutils.TEncoding
provides method GetBytes
for converting string
to TBytes
(array of bytes) and GetString
for converting TBytes
to string
. The class Sysutils.TEncoding
also provides many predefined encodings as class properties.
One way how to deal with encodings is to use only string
type in your application and use TEncoding
every time you need to use specific encoding - typically in I/O operations, DLL calls, etc...
procedure EncodingExample;
var hello,response:string;
dataout,datain:TBytes;
expectedLength:integer;
stringStream:TStringStream;
stringList:TStringList;
begin
hello := 'Hello World!Привет мир!';
dataout := SysUtils.TEncoding.UTF8.GetBytes(hello); //Conversion to UTF8
datain := SomeIOFunction(dataout); //This function expects input as TBytes in UTF8 and returns output as UTF8 encoded TBytes.
response := SysUtils.TEncoding.UTF8.GetString(datain); //Convertsion from UTF8
//In case you need to send text via pointer and length using specific encoding (used mostly for DLL calls)
dataout := SysUtils.TEncoding.GetEncoding('ISO-8859-2').GetBytes(hello); //Conversion to ISO 8859-2
DLLCall(addr(dataout[0]),length(dataout));
//The same is for cases when you get text via pointer and length
expectedLength := DLLCallToGetDataLength();
setLength(datain,expectedLength);
DLLCall(addr(datain[0]),length(datain));
response := Sysutils.TEncoding.GetEncoding(1250).getString(datain);
//TStringStream and TStringList can use encoding for I/O operations
stringList:TStringList.create;
stringList.text := hello;
stringList.saveToFile('file.txt',SysUtils.TEncoding.Unicode);
stringList.destroy;
stringStream := TStringStream(hello,SysUtils.TEncoding.Unicode);
stringStream.saveToFile('file2.txt');
stringStream.Destroy;
end;