ASCII.GetString() 在空字符处停止

ASCII.GetString() stop on null character

我有一个大问题... 我的一段代码:

string doc = System.Text.Encoding.ASCII.GetString(stream);

变量 doc 以第一个空 (/0) 字符结束(此时丢失了大量数据)。我想得到整个字符串。 更重要的是,当我复制这段代码和 运行 in immediate window in Visual Studio - 一切都很好...

我做错了什么?

不,它没有:

string doc = System.Text.Encoding.ASCII.GetString(new byte[] { 65, 0, 65 }); // A[=10=]A
int len = doc.Length; //3

但 Winforms(和 Windows API)首先截断(显示时)[=11=]

示例:https://dotnetfiddle.net/yjwO4Y

我要补充一点(在 Visual Studio 2013 年),[=11=] 正确显示但在一个地方:如果您激活文本可视化工具(放大镜),那不会不支持 [=11=] 并截断它。

为什么会这样?因为历史上有两个 "models" 字符串,NUL ([=11=]) 终止的 C 字符串(因此不能使用 [=11=] 作为字符)和 Pascal 字符串前面有长度,因此可以将 [=11=] 作为字符。来自 wiki

Null-terminated strings were produced by the .ASCIZ directive of the PDP-11 assembly languages and the ASCIZ directive of the MACRO-10 macro assembly language for the PDP-10. These predate the development of the C programming language, but other forms of strings were often used.

现在,Windows 是用 C 语言编写的,并使用以 null 结尾的字符串(但后来 Microsoft 改变了想法,COM 字符串更类似于 Pascal 字符串并且可以包含 NUL 字符)。所以 Windows API 不能使用 [=11=] 字符(除非它们是基于 COM 的,而且基于 COM 的可能经常有问题,因为它们没有针对 [ =11=]).对于 .NET,Microsoft 决定使用类似于 Pascal 字符串和 COM 字符串的东西,因此 .NET 字符串可以使用 [=11=].

Winforms 直接构建在 Windows API 之上,因此无法显示 [=11=]。 WPF 是在 .NET 中构建的 "from the ground up",因此通常它可以显示 [=11=] 字符。