我有以下文件:
abcde
kwakwa
<0x1A>
line3
linllll
其中<0x1A>
表示十六进制值为 0x1A 的字节。当尝试在 Python 中读取此文件时:
for line in open('t.txt'):
print line,
它只读取前两行,然后退出循环。
解决方案似乎是以二进制(或通用换行模式)打开文件 - 'rb' 或 'rU'。你能解释一下这种行为吗?
我有以下文件:
abcde
kwakwa
<0x1A>
line3
linllll
其中<0x1A>
表示十六进制值为 0x1A 的字节。当尝试在 Python 中读取此文件时:
for line in open('t.txt'):
print line,
它只读取前两行,然后退出循环。
解决方案似乎是以二进制(或通用换行模式)打开文件 - 'rb' 或 'rU'。你能解释一下这种行为吗?
0x1A 是 Ctrl-Z,DOS 历史上使用它作为文件结束标记。例如,尝试使用命令提示符并“键入”您的文件。它只会显示 Ctrl-Z 上方的内容。
Python 使用 Windows CRT 函数 _wfopen,它实现了“Ctrl-Z 是 EOF”语义。
内德当然是正确的。
如果您的好奇心更深入一点,那么根本原因是向后兼容性发挥到了极致。Windows 与 DOS 兼容,后者使用 Ctrl-Z 作为文本文件的可选文件结束标记。您可能不知道的是,DOS 与 CP/M 兼容,CP/M 在 PC 之前在小型计算机上很流行。CP/M 的文件系统没有跟踪文件大小到字节级别,它只跟踪软盘扇区的数量。如果您的文件不是 128 字节的精确倍数,您需要一种方法来标记文本的结尾。这篇 Wikipedia 文章暗示 Ctrl-Z 的选择是基于 DEC 使用的更古老的约定。