Линейные дроссели на 0x1A

У меня есть следующий файл:

abcde
kwakwa
<0x1A>
line3
linllll

Где <0x1A> представляет собой байт с шестнадцатеричным значением 0x1A. При попытке прочитать этот файл в Python как:

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

Он только считывает первые две строки и выходит из цикла.

Решение похоже на открытие файла в двоичном (или в универсальном режиме новой строки) - "rb" или "rU". Можете ли вы объяснить это поведение?

Ответы

Ответ 1

0x1A - это Ctrl-Z, а DOS исторически используется как маркер конца файла. Например, попробуйте использовать командную строку и введите тип файла. Он отображает содержимое только Ctrl-Z.

Python использует функцию Windows CRT _wfopen, которая реализует семантику "Ctrl-Z is EOF".

Ответ 2

Ned, конечно, правильный.

Если ваше любопытство работает немного глубже, основной причиной является обратная совместимость, принятая до крайности. Windows совместима с DOS, которая использовала Ctrl-Z как необязательный конец маркера файла для текстовых файлов. Возможно, вы не знаете, что DOS совместима с CP/M, которая была популярна на небольших компьютерах перед ПК. Файловая система CP/M не отслеживала размеры файлов до уровня байтов, но отслеживала только количество секторов гибких дисков. Если ваш файл не был точно кратным 128 байтам, вам понадобился способ отметить конец текста. Эта статья в Википедии подразумевает, что выбор Ctrl-Z был основан на еще более старом соглашении, используемом DEC.