RawByteString
- это AnsiString
без кодовой страницы, установленной по умолчанию.
Когда вы назначите другую string
этой переменной RawByteString
, вы скопируете кодовую страницу источника string
.И это будет включать в себя преобразование.Извините.
Но есть еще один способ использования RawByteString
, который предназначен для хранения простого байтового содержимого (например, содержимого поля BLOB базы данных, как array of byte
)
Подводя итог:
RawByteString
следует использовать в качестве параметра "независимой от кодовой страницы" для метода или функции; RawByteString
можно использовать в качестве типа переменной для хранения некоторых данных BLOB.
Если вы хотите уменьшить конверсию и предпочитаете использовать в своем приложении 8-битный символ string
, вам лучше:
- Не использовать универсальный *Тип 1028 *, который будет зависеть от текущей системной кодовой страницы и по которой вы будете терять данные;
- Положитесь на кодировку UTF-8, т. Е. Некоторую 8-битную кодовую страницу / кодировку, которая не потеряет никаких данных при преобразовании из или в
UnicodeString
; - Не позволяйте компиляторупокажите предупреждения о неявных преобразованиях: все преобразования должны быть сделаны явными;
- Используйте свой собственный выделенный набор функций для обработки содержимого UTF-8.
Этоименно то, что мы сделали для нашей структуры.Мы хотели использовать UTF-8 в его ядре, потому что:
- Мы полагаемся на кодирование JSON в кодировке UTF-8 для передачи данных;
- Потребление памяти будет меньше;
- Используемый 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, были глубоко оптимизированы, и версия на паскале, и версия asm для лучшей скорости.Иногда мы перегружали функции по умолчанию (например, Pos
), чтобы избежать преобразования, или Подробнее о том, как мы обрабатывали текст в платформе, можно узнать здесь: .
Последнее слово:
Если вы уверены , что в вашем приложении будет только 7-битное содержимое (без выделенных символов), вы можете использовать в своей программе тип AnsiString
по умолчанию.Но в этом случае вам лучше добавить модуль AnsiStrings
в ваше предложение uses
, чтобы иметь перегруженные строковые функции, которые позволят избежать большинства нежелательных преобразований.