【发布时间】:2011-03-09 01:00:01
【问题描述】:
已经有一些与此问题相关的问题。我认为我的问题有点不同,因为我没有实际问题,我只是出于学术兴趣而问。我知道 Windows 的 UTF-16 实现有时与 Unicode 标准(例如排序规则)相矛盾,或者更接近旧的 UCS-2 而不是 UTF-16,但出于以下原因,我将在此处保留“UTF-16”术语简单。
背景:在 Windows 中,一切都是 UTF-16。无论您是在处理内核、图形子系统、文件系统还是其他任何东西,您都在传递 UTF-16 字符串。 Unix 意义上没有语言环境或字符集。为了与中世纪版本的 Windows 兼容,有一种称为“代码页”的东西已过时但仍受支持。 AFAIK,只有一个正确且不会过时的函数可以将字符串写入控制台,即WriteConsoleW,它采用 UTF-16 字符串。此外,类似的讨论适用于输入流,我也将忽略。
但是,我认为这代表了 Windows API 中的一个设计缺陷:有一个通用函数可以用于写入所有流对象(文件、管道、控制台……),名为 WriteFile,但这个函数是 byte -面向并且不接受 UTF-16 字符串。文档建议使用WriteConsoleW 用于控制台输出,它是面向文本的,WriteFile 用于其他所有东西,它是面向字节的。由于控制台流和文件对象都由内核对象句柄表示,并且可以重定向控制台流,因此您必须为每次写入标准输出流调用一个函数,以检查句柄是表示控制台流还是文件,从而破坏多态性。 OTOH,我确实认为 Windows 在文本字符串和原始字节之间的分离(在 Java 或 Python 等许多其他系统中镜像)在概念上优于 Unix 的 char* 方法,该方法忽略编码并且不区分字符串和字节数组。
所以我的问题是:在这种情况下该怎么办?为什么即使在微软自己的库中也没有解决这个问题? .NET Framework 以及 C 和 C++ 库似乎都遵循过时的代码页模型。您将如何设计 Windows API 或应用程序框架来规避此问题?
我认为一般问题(不容易解决)是所有库都假设所有流都是面向字节的,并在此基础上实现面向文本的流。但是,我们看到 Windows 在操作系统级别确实有特殊的面向文本的流,而库无法处理这个问题。所以无论如何,我们必须对所有标准库进行重大更改。一种快速而肮脏的方法是将控制台视为仅接受一种编码的特殊面向字节的流。这仍然要求必须绕过 C 和 C++ 标准库,因为它们没有实现 WriteFile/WriteConsoleW 开关。对吗?
【问题讨论】:
-
抱歉,这个“问题”听起来像是一篇变相的博文;-)
-
这可能与我的问题有关:superuser.com/questions/157225/…