【问题标题】:Line reading chokes on 0x1A0x1A 上的线路读取扼流圈
【发布时间】:2009-01-01 15:29:35
【问题描述】:

我有以下文件:

abcde
kwakwa
<0x1A>
line3
linllll

其中&lt;0x1A&gt; 表示十六进制值为0x1A 的字节。尝试在 Python 中读取此文件时:

for line in open('t.txt'):
    print line,

它只读取前两行,然后退出循环。

解决方案似乎是以二进制(或通用换行模式)打开文件 - 'rb' 或 'rU'。你能解释一下这种行为吗?

【问题讨论】:

  • 你怎么知道这个字节代表。对我来说,它只是在记事本++中说“SUB”
  • 另一种解决方法是在 Python 2 中使用 Python 3 或 io.open();就操作系统而言,io 文件对象始终以二进制模式使用文件,因此 Windows 不会过早地“结束”文件。

标签: python windows binary-data


【解决方案1】:

0x1A 是 Ctrl-Z,DOS 历史上使用它作为文件结束标记。例如,尝试使用命令提示符并“键入”您的文件。它只会显示 Ctrl-Z 上方的内容。

Python 使用 Windows CRT 函数 _wfopen,它实现了“Ctrl-Z 是 EOF”语义。

【讨论】:

  • 提醒我,我曾经必须使用 LaTeX 构建一个 PostScript 文档,其中包含在 Windows 上创建的 PostScript 图像。我想知道为什么打印机在第一张图片后停止打印......好吧,PostScript图片文件中的最后一个字节是0x1A。
【解决方案2】:

Ned当然是正确的。

如果您的好奇心更深入一点,根本原因是向后兼容性达到了极端。 Windows 与 DOS 兼容,后者使用 Ctrl-Z 作为文本文件的可选文件结束标记。您可能不知道的是,DOS 与 CP/M 兼容,CP/M 在 PC 之前在小型计算机上很流行。 CP/M 的文件系统没有跟踪文件大小到字节级别,它只跟踪软盘扇区的数量。如果您的文件不是 128 字节的精确倍数,您需要一种方法来标记文本的结尾。 This Wikipedia article 暗示 Ctrl-Z 的选择基于 DEC 使用的更老的约定。

【讨论】:

    猜你喜欢
    • 2019-04-30
    • 2011-06-16
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多