RawByteString
is an AnsiString
默认情况下没有设置代码页。
当您分配另一个string
对此RawByteString
变量,您将复制源代码页string
。这将包括转换。对不起。
但还有另一种用途RawByteString
,用于存储纯字节内容(例如数据库 BLOB 字段内容,就像array of byte
)
总结一下:
-
RawByteString
应该用作方法或函数的“代码页不可知”参数;
-
RawByteString
可以作为变量类型来存储一些BLOB数据。
如果你想减少转换,宁愿使用8位字符string
在您的应用程序中,您应该更好:
- 不要使用通用的
AnsiString
类型,这取决于当前的系统代码页,并且您将丢失数据;
- 依赖 UTF-8 编码,即一些 8 位代码页/字符集,在从 UTF-8 编码或转换为 UTF-8 编码时不会丢失任何数据
UnicodeString
;
- 不要让编译器显示warnings关于隐式转换:所有转换都应显式进行;
- 使用您自己的专用函数集来处理 UTF-8 内容。
这正是我们为框架所做的。我们希望在其内核中使用 UTF-8,因为:
- 我们依靠UTF-8编码的JSON进行数据传输;
- 内存消耗会更小;
- 使用过的SQLite3引擎会将文本以 UTF-8 形式存储在其数据库文件中;
- 我们想要一种处理 Unicode 文本的方法,并且所有版本的 Delphi(从 Delphi 6 到 XE)都不会丢失数据,并且
WideString
不是一个选择,因为它非常慢并且您遇到了相同的隐式转换问题。
但是,为了实现最佳速度,我们编写了一些优化函数来处理自定义字符串类型:
{{ RawUTF8 is an UTF-8 String stored in an AnsiString
- use this type instead of System.UTF8String, which behavior changed
between Delphi 2009 compiler and previous versions: our implementation
is consistent and compatible with all versions of Delphi compiler
- mimic Delphi 2009 UTF8String, without the charset conversion overhead
- all conversion to/from AnsiString or RawUnicode must be explicit }
{$ifdef UNICODE} RawUTF8 = type AnsiString(CP_UTF8); // Codepage for an UTF8string
{$else} RawUTF8 = type AnsiString; {$endif}
/// our fast RawUTF8 version of Trim(), for Unicode only compiler
// - this Trim() is seldom used, but this RawUTF8 specific version is needed
// by Delphi 2009/2010/XE, to avoid two unnecessary conversions into UnicodeString
function Trim(const S: RawUTF8): RawUTF8;
/// our fast RawUTF8 version of Pos(), for Unicode only compiler
// - this Pos() is seldom used, but this RawUTF8 specific version is needed
// by Delphi 2009/2010/XE, to avoid two unnecessary conversions into UnicodeString
function Pos(const substr, str: RawUTF8): Integer; overload; inline;
我们保留了RawByteString
处理 BLOB 数据的类型:
{$ifndef UNICODE}
/// define RawByteString, as it does exist in Delphi 2009/2010/XE
// - to be used for byte storage into an AnsiString
// - use this type if you don't want the Delphi compiler not to do any
// code page conversions when you assign a typed AnsiString to a RawByteString,
// i.e. a RawUTF8 or a WinAnsiString
RawByteString = AnsiString;
/// pointer to a RawByteString
PRawByteString = ^RawByteString;
{$endif}
/// create a File from a string content
// - uses RawByteString for byte storage, thatever the codepage is
function FileFromString(const Content: RawByteString; const FileName: TFileName;
FlushOnDisk: boolean=false): boolean;
源代码可用在我们的存储库中。在本单元中,对UTF-8相关功能进行了深度优化,同时提供了pascal和asm版本,以获得更好的速度。我们有时会重载默认函数(例如Pos
)以避免转换,或者有关我们如何在框架中处理文本的更多信息是可以在这里找到.
遗言:
如果你是sure您的应用程序中只有 7 位内容(无重音字符),您可以使用默认值AnsiString
输入你的程序。但在这种情况下,您最好添加AnsiStrings
单位在你的uses
子句具有重载的字符串函数,这将避免大多数不需要的转换。