WeG*_*ars 17 delphi utf-8 utf-16
我必须在国际上分发我的应用程序.
假设我有一个用户输入一些文本的控件(如备忘录).用户可以是日语,俄语,加拿大等.我想将字符串保存为磁盘作为TXT文件供以后使用.我将使用MY OWN函数来编写文本而不是TMemo.SaveToFile().
我如何将字符串保存到磁盘?采用UTF8或UTF16格式?
Com*_*sMS 30
它们之间的主要区别在于UTF8向后兼容ASCII.只要您只使用前128个字符,非Unicode识别的应用程序仍然可以处理数据(这可能是优势或劣势,具体取决于您的方案).特别是,当切换到UTF16时,每个 API函数都需要针对16位字符串进行调整,而使用UTF8时,如果不进行任何字符串处理,通常可以保持旧的API函数不变.UTF8也不依赖于字节序,而UTF16则不依赖于字符串I/O.
一个常见的误解是UTF16更容易处理,因为每个字符总是占用两个字节.不幸的是,这不是真的.UTF16是一种可变长度编码,其中一个字符可能占用2或4个字节.因此,与UTF8相关的关于可变长度问题的任何困难也适用于UTF16.
最后,存储大小:关于UTF16的另一个常见误区是,对于大多数外语来说,它比UTF8更具存储效率.UTF8 为所有欧洲语言占用较少的存储空间,每个字符可以编码一个或两个字节.非BMP字符在UTF8和UTF16中占用4个字节.UTF16占用较少存储空间的唯一情况是文本主要由U + 0800到U + FFFF范围内的字符组成,其中存储了中文,日文和印地文的字符.
James McNellis在BoostCon 2014上发表了精彩的演讲,详细讨论了不同编码之间的各种权衡.虽然谈话的标题是C++中的Unicode,但整个上半部分实际上与语言无关.一个完整的谈话录像可在Boostcon的YouTube频道,而幻灯片可以在github上找到.
Mar*_*ema 27
取决于您的数据的语言.
如果您的数据主要使用西方语言并且您希望减少所需的存储量,请使用UTF-8,因为这些语言大约需要UTF-16的一半存储空间.您将在读取数据时支付罚金,因为它将/需要转换为UTF-16,这是Windows默认值并由Delphi(Unicode)字符串使用.
如果您的数据主要使用非西方语言,则UTF-8可以占用比UTF-16更多的存储空间,因为对于某些人来说,每个字符最多可能占用6 个字节.(见@KennyTM的评论)
基本上:使用用户数据的代表性样本进行一些测试,并查看哪些在存储要求和加载时间方面表现更好.我们有一些惊喜,UTF-16比我们想象的要慢.由于磁盘访问,因为UTF-16中的数据量更大,因此无需从UTF-8转换为UTF-16的性能增益丢失.
Arn*_*hez 10
首先,请注意Windows下的标准编码是UCS2(直到Windows 2000)或UTF-16(从XP开始),Delphi本机" string
"类型使用自Delphi 2009(string=UnicodeString char=WideChar
)以来的相同本机格式.
在所有情况下,假设1 WideChar
== 1个Unicode字符是不安全的- 这是代理问题.
关于UTF-8或UTF-16的选择,它取决于存储本身:
string
布局,当然还有默认的数据库API布局;例如,我们使用UTF-8作为我们的Client-Server框架,因为我们使用JSON作为交换格式(需要UTF-8),并且因为SQlite3喜欢UTF-8.当然,我们必须编写一些专用的函数和类,以避免转换为/从string
(string=UnicodeString
自Delphi 2009以来类型的速度很慢,并且string=AnsiString
在Delphi 2009之前使用类型时可能会丢失一些数据.请参阅此文章和本单元) .最简单的方法是依赖string=UnicodeString
类型,使用直接处理UTF-16编码的RTL函数,并避免转换.不要忘记你以前的问题.
如果磁盘空间和读/写速度有问题,请考虑使用压缩而不是更改编码.有实时压缩(比ZIP快),如LZO或我们的SynLZ.
归档时间: |
|
查看次数: |
5773 次 |
最近记录: |