代码之家  ›  专栏  ›  技术社区  ›  Imran

不同线路在不同平台终止的历史原因

  •  37
  • Imran  · 技术社区  · 17 年前

    为什么DOS/Windows和Mac决定使用\r\n和\r作为行尾而不是\n?这只是试图与Unix“不同”的结果吗?

    现在Mac OS X是Unix(类Unix),苹果是否从\r切换到了?

    4 回复  |  直到 15 年前
        1
  •  35
  •   Mark Harrison    16 年前

    DOS从CP/M继承了CR-LF行尾(您称之为\r\n,只是使ascii字符显式)。CP/M从影响CP/M设计师Gary Kildall的各种DEC操作系统继承了它。

    使用CR-LF,以便电传打字机将打印头返回到左边距(CR=滑架返回),然后移动到下一行(LF=换行)。

    Unix人员在设备驱动程序中处理了这一点,并在必要时将LF转换为CR-LF,输出到需要它的设备。

    如您所料,Mac OS X现在使用LF。

        2
  •  20
  •   Steve314    9 年前

    真的添加到@Mark Harrison。..

    那些告诉你Unix“只是输出程序员指定的文本”而DOS坏了的人是完全错误的。还有人声称,DOS在看到EOF字符时标记EOF是愚蠢的,这引发了EOF字符到底是用来做什么的问题。

    文本文件行结尾没有一个真正的约定,只有特定于平台的约定。毕竟,即使是CR-LF、CR和LF也不是唯一使用的行尾约定,ASCII甚至从来不是唯一的字符集。问题在于C标准库和运行时,它没有抽象出这种依赖于平台的细节。其他第三代语言(如Pascal甚至Basic)至少在一定程度上管理了它。因此,当为其他平台编写C编译器时,需要运行时库黑客来实现与现有源代码和书籍的兼容性。

    事实上,最初需要对控制台I/O进行字符串转换的是Unix和Multics,因为用户通常坐在需要CR LF线端的ASCII终端上。不过,这种翻译是在设备驱动程序中完成的,目的是抽象出设备的具体细节,假设最好采用一种约定并对存储的文本文件严格遵守。

    C文本I/O黑客的原理与CygWin现在所做的相似,黑客攻击Linux运行时,使其在Windows上正常工作。有一段真正的黑客历史,即将把它们变成Unix的翻版,但还有Wine,将Linux变成Windows。奇怪的是,你可以在 CygWin FAQ (2013年添加了Internet Archive链接-该页面已不存在)。也许这只是他们的幽默感,因为他们基本上是在做他们批评的事情,但规模要大得多;-)

    C++标准库(无论在什么平台上实现)使用iostream避免了这个问题,iostream抽象了换行符。 对于输出,这很适合我。对于输入,我需要更多的控制,所以我要么逐个字符地解释,要么使用扫描生成器。

    [ 编辑 事实证明,上述被剔除的说法是不正确的,而且从来都不是。这个 std::endl 字面意思是a \n 然后冲水。这个 n 完全一样 n 在C中,它往往被称为“新行”,但它实际上是一个ASCII换行符,必要时会被运行时翻译。有趣的是,错误的假设会变得如此根深蒂固,以至于你永远不会质疑它们——基本上,出于兼容性的原因,C++别无选择地做C所做的事情(除了在上面添加更多层),这应该是显而易见的。]

    我的POV中最大的责任是C,但C并不是唯一一个没有预料到它会转移到其他平台的项目。指责比尔·盖茨简直是疯了——他所做的只是购买并打磨了当时流行的CP/M的变体。真的,这只是历史——这也是我们不知道大多数文本文件中128到255代表什么的原因。考虑到很容易应对所有三种线端约定,奇怪的是,一些开发人员仍然坚持“我的平台约定是唯一正确的方式,不管你喜欢与否,我都会强迫你”的态度。

    此外,Unicode行分隔符代码点U+2028是否会在未来的文本文件中取代所有这些约定? ;-)

        3
  •  8
  •   tzs    16 年前

    值得注意的是,CRLF几乎是互联网标准。也就是说,几乎所有面向线路的标准互联网协议都使用CRLF。SMTP、POP、IMAP、NNTP等。电子邮件正文由以CRLF结尾的行组成。

        4
  •  0
  •   Jerry Jeremiah    5 年前

    根据维基百科:一开始,程序必须在LF之前添加额外的CR字符来减慢程序速度,这样打印机就有时间跟上CP/M,后来Windows使用了这种方法。但是Multics的打印机驱动程序会自动添加额外的字符,这样程序就不必这样做了,Unix开发人员也不必这样。但这些都不能解释为什么早期的Mac没有这样做(现在它们是基于Unix的)。

    https://en.wikipedia.org/wiki/Newline#History :

    CR+LF序列通常用于许多早期的计算机系统,这些系统采用了电传打字机,通常是电传打字机33型ASR作为控制台设备,因为需要这个序列将这些打印机定位在新生产线的起点。换行符分为两个函数掩盖了这样一个事实,即打印头无法及时从最右侧返回到下一行的开头,以打印下一个字符。在CR之后打印的任何字符通常会打印为页面中间的污迹,而打印头仍在将滑架移动回第一位置。“解决方案是将换行符设置为两个字符:CR用于将滑架移动到第一列,LF用于将纸张向上移动。”[1]事实上,通常需要发送额外的字符——不连续的CR或NUL,这些字符会被忽略,但会给打印头时间移到左边距。许多早期的视频显示还需要多个字符时间来滚动显示。

    在这种系统上,应用程序必须直接与电传打字机对话并遵循其惯例,因为设备驱动程序向应用程序隐藏此类硬件细节的概念尚未得到很好的发展。因此,为了满足电传打字机的需求,通常会编写文本。DEC的大多数小型计算机系统都使用这种惯例。CP/M也使用它来在小型计算机使用的相同终端上打印。从那时起,MS-DOS(1981)采用了CP/M的CR+LF以兼容,这一惯例被微软后来的Windows操作系统继承。

    Multics操作系统于1964年开始开发,仅使用LF作为换行符。Multics使用设备驱动程序将此字符转换为打印机所需的任何序列(包括额外的填充字符),并且单字节更便于编程。似乎更明显的[需要引用]选择CR没有被使用,因为CR提供了用一行叠加另一行以创建粗体和删除线效果的有用功能。也许更重要的是,单独使用LF作为线路端接器已经被纳入最终的ISO/IEC 646标准的草案中。Unix遵循了Multics的做法,后来类Unix系统也遵循了Unix。这在Windows和类Unix操作系统之间造成了冲突,在一个操作系统上编写的文件无法被另一个操作操作系统正确格式化或解释(例如在记事本等Windows文本编辑器中编写的Unix shell脚本)。