2011-05-18 104 views
10

我终于升级到Delphi XE。我有一个单元库,我使用字符串来存储普通的ANSI字符(A和U之间的字符)。我101%肯定我永远不会在这些地方使用UNICODE角色。Delphi XE - 我应该使用String还是AnsiString?

我想将所有其他库转换为Unicode,但对于这个特定的库,我认为最好坚持使用ANSI。优点是内存需求,因为在某些情况下,我加载了非常大的TXT文件(仅包含Ansi字符)。缺点可能是当我使这些库与普通(unicode)库进行交互时,我必须做大量的类型转换。

有一些通用的指导方针,可以显示何时转换为Unicode以及何时坚持使用Ansi?

回答

7

一般指导原则的问题在于,类似这样的事情可能对某人的情况非常具体。你的例子就是其中之一。

不过,对于谷歌搜索的人,在这里到达,一些一般性的指导方针是:

  • 是,转换为Unicode。不要试图让旧应用完全使用AnsiString s。原因是整个VCL是Unicode的,你不应该试图混合这两个,因为每次你将一个Unicode字符串分配给一个ANSI字符串时,你就会进行转换,这是一个有损转换。试图保持旧的方式,因为它的工作较少(或类似的原因)会导致你痛苦;只需拥抱新的string类型,转换并使用它。

  • 而不是随机混合这两个,明确地执行任何你需要的转换 - 例如,如果你从程序的旧版本加载数据,你知道它将是ANSI,所以阅读它成为一个Unicode字符串在那里,就是这样。之后,它将是Unicode。

  • 你不应该改变你的string变量的类型 - string pre-D2009是ANSI,而在D2009和alter是Unicode。相反,请按照compiler warnings并观察您使用哪种字符串方法 -​​ 有些仍然采用AnsiString参数,我觉得这一切都令人困惑。编译器会告诉你。

  • 如果使用字符串来保存字节(换句话说,将它们用作字节数组,因为字符是字节)切换到TBytes。您可能会遇到特定的问题,如加密(字符串不再是字节/字符,所以'字符'为'字符',你可能会得到不同的输出)。读取文本文件(使用流类和TEncoding);坦率地说,还有其他的东西。在这里搜索,大多数事情都被问过。

提意见,请添加更多的建议...我一直都用C++ Builder中,不德尔福,并且有可能相当德尔福一些具体的事情我不知道。

现在为您的具体问题:你应该转换这个库吗?

如果:

  • A之间的值和U是真正的永远只能在这个范围内,并
  • 这些值表示的字符(A真的是A,而不是字节值65 - 如果是这样,使用TB的),和
  • 您加载大的文本文件和内存是个问题

则没有转换为Unicode的,并没有切换你的string s到AnsiString s,是有道理的。

注意:

  • 还有每次你从ANSI转换为Unicode时间
  • 你可以使用UTF8String,这是转换时不会有损AnsiString特定类型是开销,仍然将大部分文本(罗马字符)存储在单个字节中
  • string的所有实例更改为AnsiString可能有点工作,您需要检查与它们一起调用的所有方法,以查看是否有太多隐式转换正在执行med(用于性能)等
  • 您可能需要更改库的外层以使用Unicode,以便转换代码或ANSI/Unicode编译器警告对您的库的用户不可见
  • 如果您转换为Unicode ,字符集(不记得语法,也许if 'S' in MySet?)won't work。从字符A到U的描述中,我可以猜测你想使用这种语法。

我的推荐?就我个人而言,根据您提供的信息来做这件事的唯一原因是内存使用情况,以及可能的性能,这取决于您使用这么大数量的A..U s所做的事情。如果这真的很重要,它既是驱动程序又是约束条件,你应该转换为ANSI。

+0

谢谢大卫。我开始把这个库转换成Ansi,这很合理。我还看到,这个库和其他经典(unicode)库之间的交互作用并不像我担心的那么大。大多数情况下,我必须在画布上“打印”这些A-U字符串。太糟糕了,我以前没有用UTF8String的想法。我已经开始了我的转换。但如果我看到问题,我会明确地想到它。再次感谢。 – Ampere 2011-05-19 09:44:35

3

通常只有在使用AnsiString时,如果重要的是字符是单个字节,否则使用字符串可确保将来与Unicode兼容。

0

你总有需要检查所有的图书馆,因为Delhpi XE所有Windows API函数代替它们的Unicode-类似物等,如果你将永远不会使用UNICODE,你需要使用Delphi 7

+1

如果你不需要Unicode并且更新更新,那么Delphi 2007可以正常工作。 – Johan 2011-05-18 19:03:41

+0

我没有说我不使用UNICODE(即使它是真的,我也不关心它)。我只对这个特定的库使用ANSI字符串,因为我使用了缩小字母表,我需要小字符串来减少内存需求。 – Ampere 2011-05-19 09:46:44

4

您应该能够在本单元与其客户端之间的接口处结束转换。内部使用AnsiString并在其他地方使用字符串,你应该没问题。

+0

@Altar - 我认为大卫已经非常整齐地总结了它(他通常会这么做)。我不确定为什么如果你有精心设计的接口来访问Ansi数据,你需要'大量的类型转换' - 只需在Ansi和Unicode之间的阈值函数中使用System.StringToWideChar - 参见ms-help: // Xe help中的//embarcadero.rs_xe/vcl/System.StringToWideChar.html“从AnsiString返回一个UNICODE字符串。” HTH MN – Vector 2011-05-20 05:16:48

+0

@mikey或甚至更简单UnicodeString(s) – 2011-05-20 05:21:50

+0

我知道 - 这是我自己做的,我从来没有遇到过问题 - 但由于有一个记录的VCL功能,我认为这会带来更多的重量......: ) – Vector 2011-05-20 06:21:34

0

在本机中无处不在地使用AnsiString,然后如果碰巧不正确地访问这些例程,您将得到编译器警告错误(您永远不应该忽略)来处理String到AnsiString的转换错误。

或者,也许最好根据您的情况,简单地将所有内容转换为UTF8。

0

如果您没有足够的时间正确转换代码,请使用Ansi字符串。 Ansi字符串的使用实际上只是为了向后兼容 - 据我所知C#没有与Ansi字符串等价的字符串。否则使用标准的Unicode字符串。如果你在我的网站上看看,我有一个完整的字符串例程单元(大约5,000 LOC),它与Delphi 2007(非Uniocde)和XE(Unicode)一起使用,只有“字符串”接口,几乎包含所有的您可能会遇到转换问题。

+0

“Ansi字符串的使用实际上只是为了向后兼容” - - - 其实在我的情况下是为了内存要求。 UNICODE将使我的程序需要更多的RAM 2倍!这将推翻今天普通(2-4GB RAM)计算机的限制。我的所有其他图书馆已经转换为UNICODE。 – Ampere 2011-05-19 09:49:12