我对C#UTF8编码感到困惑...
假设这些“事实”是正确的:
根据C#参考,每个字符的可接受范围为0x0000到0xFFFF。我不明白另一个字符是什么,它在0xFFFF之上,在Unicode协议中定义的?
与C#相比,当我使用Python编写UTF8文本时-它涵盖了所有预期范围(0x0000到0x10FFFF)。例如:
u"\U00010000" #WORKING!!!
这对C不起作用。此外,当我将Python中的字符串(单字符)写入文本文件,然后从C#中读取时,这个单字符文档变成了C#中的2个字符!
# Python (write):
import codecs
with codes.open("file.txt", "w+", encoding="utf-8") as f:
f.write(text) # len(text) -> 1
// C# (read):
string text = File.ReadAllText("file.txt", Encoding.UTF8); // How I read this text from file.
Console.Writeline(text.length); // 2
为什么?如何修复?
Unicode有所谓的平面(wiki)。
如您所见,C#schar
type仅支持第一个平面,即平面0,即基本的多语言平面。
我知道C#使用UTF-16编码,所以我有点惊讶地看到,它不支持超出char数据类型第一个平面的代码点。(我自己没有遇到过这个问题……)。
这是char实现中的人为限制,但可以理解。的设计者。NET可能不想将自己的字符数据类型的抽象与Unicode定义的抽象联系起来,以防该标准无法生存(它已经取代了其他标准)。当然,这只是我的猜测。它只是“使用”UTF-16来表示内存。
UTF-16使用一种技巧将高于0xFFFF的代码点压缩为16位,您可以在这里阅读到。从技术上讲,这些代码点由2个“字符”组成,即所谓的代理项对。从这个意义上讲,它打破了“一个代码点=一个字符”的抽象。
您可以通过使用
string
和char
数组来解决这个问题。如果您有更具体的问题,您可以在StackOverflow和其他地方找到大量关于在. NET中处理所有Unicode代码点的信息。
根据C#参考,每个字符的可接受范围为0x0000到0xFFFF。我不明白另一个字符是什么,它在0xFFFF之上,在Unicode协议中定义的?
不幸的是,C#/。NETchar
不代表Unicode字符。
字符是0x0000到0xFFFF范围内的16位值,表示一个“UTF-16代码单元”。U 0000–U D7FF和U E000–U FFFF范围内的字符由相同数字的代码单元表示,因此在那里一切都很好。
通过将每个字符表示为两个UTF-16代码单元,将U 010000到U 10FFFF范围内使用频率较低的其他字符压缩到剩余空间0xD800–0xDFFF中,因此Python字符串“U00010000”的等价物是C#“\uD800\uDC00”
。
为什么?
之所以如此疯狂,是因为Windows NT系列本身使用UTF-16LE作为本机字符串编码,以便于互操作。NET选择了相同的。WinNT选择了当时被认为是UCS-2的编码,并且没有任何令人讨厌的代理代码单元对,因为在早期,Unicode只有U-FFFF以下的字符,并且认为这将是所有人都需要的。
怎么修?
没有一个好的解决方案。其他一些不幸的语言将其字符串类型基于UTF-16代码单元(Java、JavaScript),开始向其字符串添加方法来对它们进行操作,一次计数一个代码点;但是目前在. NET中没有这样的功能。
通常情况下,您实际上并不需要使用适当的代码点项和索引来持续计算/查找/拆分/排序/etc字符串。但是当你真的这样做的时候,在. NET中,你就处于一个糟糕的时期。您最终不得不重新实现每个通常微不足道的方法,方法是手动遍历每个char
并检查它是否是双字符代理对的一部分,或者将字符串转换为代码点整数数组并返回。无论如何,这都不是很有趣。
一个更优雅、更实用的选择是发明一台时间机器,这样我们就可以将UTF-8设计追溯到1988年,并阻止UTF-16的存在。
我有一个项目,使用SonarQube来分析我的代码。正如标题所示,尽管我有多个JUnit测试,但在SQ报告(在我的服务器上)中覆盖率指标总是显示为0。我目前运行以下命令 在詹金斯建立我的项目时(詹金斯·马文项目)。 我有类似的问题前一段时间在不同的项目。我设法通过这篇文章解决了它。然而,这一次却无济于事。搜索了一下,找到了第1条和第2条(还有一些想法类似的)。两人都提出了一些好建议,但不幸的是,没
问题内容: Ada,Pascal和许多其他语言都支持范围,这是对整数进行子类型的一种方式。范围是一个有符号整数值,范围从一个值(第一个)到另一个值(最后一个)。实现一个在OOP中执行相同操作的类很容易,但是我认为本机支持该功能可以使编译器进行其他静态检查。 我知道无法静态地验证范围内定义的变量不会“溢出”运行时(即由于输入错误),但是我认为可以做些什么。我考虑了按合同设计方法(Eiffel)和Sp
我想知道为什么我的简单spring boot项目不再有效。它基本上直接来自spring示例,其中一个控制器说hello world。我使用的是spring boot starter jetty和spring boot v1.1.10(也尝试了1.2.0)。我有一些使用嵌入式solr的单元测试,所以solr核心被标记为<代码> 我认为测试范围的依赖关系不应该干扰编译范围的依赖关系,并且“仅适用于测试
我们有一个多模块的maven项目。 每个模块都有一对testng和powermock单元测试用例。我们正在使用jacoco进行代码覆盖率报告。但是,jacoco在分析单元测试复盖率时基于testng单元测试用例,而忽略了powermock单元测试用例。因此,总的代码覆盖率越来越低。 如何配置jacoco来同时获取testng和jacoco测试用例?
似乎有几个问题,这些问题很老了,而且从Java 8对Jacoco的支持开始就发生了变化。 我的项目包含以下结构 我已经这样配置了 主要聚甲醛.xml 一个Pom.xml B pom.xml 我正在执行这个命令< code>mvn clean package。我可以看到jacoco.exec正在生成,但是我看不到任何验证数据的HTML报告。 请帮帮我。另一点是,我的配置对于项目是否正确? 更新 已识
几天来,我一直在努力将JaCoCo的报告集成到SonarQube 5.0.1中。我总是在声纳曲中阅读0.0%的覆盖率。 TeamCity 9生成了一个testresults.xml和一个jacoco.exec文件,我将其用于声纳转轮。TeamCity显示覆盖范围,因此exec文件接缝很好。Java代码分析基本上在SonarQube(FindBugs、PMD等)中工作。 我有一个仍在使用Ant构建的