Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在与UNIX/Linux环境交互时使用UTF-8编码?_Linux_Unix_Encoding - Fatal编程技术网

为什么在与UNIX/Linux环境交互时使用UTF-8编码?

为什么在与UNIX/Linux环境交互时使用UTF-8编码?,linux,unix,encoding,Linux,Unix,Encoding,我知道这是惯例,但为什么?有没有真正的技术原因来解释为什么任何其他方法都是一个非常糟糕的主意,或者仅仅是基于编码和向后兼容性的历史?此外,不使用UTF-8,而是使用其他编码(最显著的是UTF-16)有什么危险 编辑:通过交互,我主要指的是shell和libc 我认为主要是UTF8与ASCII的向后兼容性 对于“危险”问题的答案,您需要指定“互动”的含义。您的意思是与shell、libc还是与内核进行交互?是的,这是出于兼容性原因。UTF-8向后兼容ASCII码。Linux/Unix是基于ASCI

我知道这是惯例,但为什么?有没有真正的技术原因来解释为什么任何其他方法都是一个非常糟糕的主意,或者仅仅是基于编码和向后兼容性的历史?此外,不使用
UTF-8
,而是使用其他编码(最显著的是
UTF-16
)有什么危险


编辑:通过交互,我主要指的是
shell
libc

我认为主要是UTF8与ASCII的向后兼容性


对于“危险”问题的答案,您需要指定“互动”的含义。您的意思是与shell、libc还是与内核进行交互?

是的,这是出于兼容性原因。UTF-8向后兼容ASCII码。Linux/Unix是基于ASCII的,所以它是有意义的。

部分原因是文件系统期望NUL('\0')字节来终止文件名,因此UTF-16无法正常工作。您必须修改大量代码才能进行更改。

我认为7位ASCII很好

说真的,Unicode在体系结构中是相对较新的,它与ASCII向后兼容,并且为典型文件使用更少的空间(一半),因为它每个代码点(字符)使用1到4个字节,而每个代码点(字符)使用2或4个字节


UTF-16更适合内部程序使用,因为其宽度更简单。它的前身UCS-2每个代码点正好有2个字节。

现代Unix使用UTF-8,但这并不总是正确的。在只有几年历史的RHEL2上,默认值是 $ locale LANG=C LC_CTYPE="C" LC_NUMERIC="C" LC_TIME="C" LC_COLLATE="C" LC_MONETARY="C" LC_MESSAGES="C" LC_PAPER="C" LC_NAME="C" LC_ADDRESS="C" LC_TELEPHONE="C" LC_MEASUREMENT="C" LC_IDENTIFICATION="C" LC_ALL= $locale LANG=C LC_CTYPE=“C” LC_NUMERIC=“C” LC_TIME=“C” LC_COLLATE=“C” LC_MONETARY=“C” LC_MESSAGES=“C” LC_PAPER=“C” LC_NAME=“C” LC_ADDRESS=“C” LC_TELEPHONE=“C” LC_MEASUREMENT=“C” LC_IDENTIFICATION=“C” LC_ALL=C/POSIX语言环境应为7位ASCII兼容编码


然而,正如Jonathan Leffler所说的,任何允许字符序列中包含NUL字节的编码在Unix上都是不可行的,因为系统API不受语言环境的影响;字符串都假定为以\0结尾的字节序列。

我认为这是因为期望ASCII输入的程序将无法处理UTF-16之类的编码。对于大多数字符(在0-255范围内),这些程序将高字节视为NUL/0字符,在许多语言和系统中用于标记字符串的结尾。这种情况在UTF-8中不会发生,UTF-8的设计目的是避免嵌入NUL,并且字节顺序不可知

正如jonathan leffler提到的,主要问题是ASCII空字符。C传统上希望字符串以null结尾。因此,标准C字符串函数将阻塞任何UTF-16字符,该字符包含相当于ASCII null(0x00)的字节。虽然您当然可以使用广泛的字符支持进行编程,但UTF-16并不是Unicode的合适外部编码

此外,UTF-16和UTF-32具有大端和小端方向。为了解决这个问题,您需要外部元数据,比如MIME类型,或者一个。它指出

其中UTF-8以透明方式用于 8位环境,使用BOM表 会干扰任何协议或协议 需要特定文件的文件格式 ASCII字符开头, 例如在 unixshell脚本的开始


UTF-16的前身称为UCS-2,不支持代理项对。应该避免使用UCS-2。

我认为,当Microsoft开始使用双字节编码时,0xffff以上的字符尚未分配,因此使用双字节编码意味着没有人需要担心字符长度不同


既然有超出此范围的字符,那么您将不得不处理不同长度的字符,为什么会有人使用UTF-16?如果微软今天设计unicode支持,我怀疑他们会做出不同的决定。

我不认为宽度要简单得多。您仍然需要扫描整个字符串。如果你正在处理大量的CJK文本,那么UTF-16实际上可以比UTF-8更紧凑,因此可能值得使用,否则我会在任何地方都使用UTF-8。没错,UTF-16已经失去了UCS-2的巨大优势。(UTF-16已经失去了UCS-2的巨大优势)…但获得了Unicode字符的完整范围。如果应该避免使用UCS-2,那么MS Windows也应该避免:)显然,Windows支持代理项对,与UCS2不同。它不必是ASCII兼容编码,但POSIX标准规定“所有位为零的字节应解释为与移位状态无关的空字符。因此,所有位为零的字节永远不会出现在字符的第二个或后续字节中。“这意味着不允许使用UTF-16和UTF-32,但UTF-8是允许的。Windows通过复制整个Windows API版本,增加了对UTF-16的支持。添加对UTF-8的支持要简单得多。实际上,Windows通过这样做添加了对UCS-2的支持,然后“重新开始640k”,结果发现16位是不够的…;-)@dan04考虑到NT早于UTF-8,使用UTF-8而不是UCS2编写NT是很困难的。这需要非凡的远见。还有,“/”(Unix路径分隔符)。UTF-8最初被称为文件系统安全通用字符集转换格式(FSS-UTF)。@skynet:注意NULL是一个NULL指针常量;NUL是ASCII字符代码0的缩写。它们是不同的。更重要的是,NT设计时UTF-8并不存在。