"\x1a" で入力が止まってしまう

Windowsで "\x1a" を含むテキストファイルをCPythonに読ませると、途中で読み込みが停止してしまうようだね。

# CPython 2.7.2 on Win32
with open('a.txt', 'wb') as fout:
    fout.write("abc\x1adef")

with open('a.txt', 'r') as fin:
    print fin.read()  # 出力: abc

そもそも、C言語の fgets() レベルで読み込みが止まる。これはCランタイム ライブラリ(CRT)の仕様なのか?

#include <stdio.h>

int main(void)
{
    FILE *fp;
    char sbuf[256];

    fp = fopen("a.txt", "r");
    if (NULL == fp) {
        fputs("IOError\n", stderr);
        return 1;
    }

    if (fgets(sbuf, 256, fp)) {
        fputs(sbuf, stdout);  /*  出力: abc  */
    }

    fclose(fp);
    return 0;
}

"\x1a" は Ctrl-z を押すと発行され、ファイルやユーザー入力の終わりを表す。なので、まったく納得できない動作ではないのだが、DebianPythonでは問題にならないんだよな(Ctrl-d に相当する "\x04" を含んでいても問題なく読める)。

おもしろいことに、ファイルを universal newline mode で開くと、問題なく全て読むことができる。

with open('a.txt', 'U') as fin:
    print fin.read()

これは、U フラグを指定すると、内部的にはバイナリモードでファイルが開かれるからだと思われる。その場合、改行コードの処理はCRTではなくCPythonの方で行われる。この方法で問題を回避するのが一番かんたんかな。