在.Net中关于Unicode处理的related question中,John Skeet表示:
如果你很高兴忽略代理对,UTF-16有一些不错的属性,主要是因为每个代码单元的大小是不变的。 您知道为给定数量的代码单元分配多少空间......
但是,您如何知道代码单元大小是什么,甚至是每个代码点的编码是否具有可变数量的代码单元?
首先,我可以通过调用相关GetMaxCharCount(nBytes)
个实例的GetMaxByteCount(nChars)
和System.Text.Encoding
函数来轻松确定。例如,有8个输入字节,我们将分别为ASCII / UTF-8,UTF-16 / UCS-2和UTF-32 / UCS-4获得不超过8,4和2个解码字符;但是对于8个输入字符,我们将获得8个字节用于ASCII以及除上述字符之外的其他编码用于其他编码,这表示它们的大小恒定性或可变性。但是,这些函数几乎没有返回有用的结果:
MaxChars MaxBytes
8 bytes 8 chars
---------------------------
ASCII 8 chars 9 bytes <--- Leftover chars in ASCII? O_o
UTF-8 9 chars 27 bytes
UTF-16 5 chars 18 bytes
UTF-32 6 chars 36 bytes <--- More chars than UTF-16? O_o
这种行为是故意的,因为他们的文档清楚地说:
请注意,
GetMaxCharCount
考虑了先前编码器操作的剩余字节的最坏情况。对于大多数代码页,将值0传递给此方法将检索大于或等于1的值。GetMaxCharCount(N)
不一定与N * GetMaxCharCount(1)
的值相同。请注意
GetMaxByteCount
考虑先前解码器操作的潜在剩余代理。由于解码器,将值1传递给方法会检索2以进行单字节编码,例如ASCII。如果需要此信息,您应该使用IsSingleByte
属性。GetMaxByteCount(N)
不一定与N * GetMaxByteCount(1)
相同。
那是不那么清楚的是那些(或其他?)函数如何应用于动态确定代码单元大小的任务,而不是从硬编码查找表中应用有限数量的编码?我找到的唯一可行的方法是“if IsSingleByte
,然后单位大小是1个字节,字符大小是常量”,但如果仅用于单字节编码,则根本不需要这样。那么任意编码的一般解决方案是什么?