【问题标题】:cannot read ascii character 26?无法读取 ascii 字符 26?
【发布时间】:2013-12-26 15:03:15
【问题描述】:

我在文本模式的文件中写了一个流。

# python code
f = open("somewhere in my computer","w")
f.write("Hello\nWorld")
f.write(chr(26)) # writing ascii character #26 to file 
f.write("hhh")
f.close()

我无法读取 ASCII 字符 #26 之后的字节。我知道我应该用二进制模式打开文件。是 ascii 字符 #26 EOF 字符。如您所知,没有这样的东西,即没有EOF 字符。那么问题是什么?这是操作系统相关的问题吗? (我在 Microsoft Windows 中尝试过)。

【问题讨论】:

  • 为我工作 (OSX)。贴出你用来阅读的代码。
  • f = open("somewhere in my computer","r") t = f.read() print len(t) # 告诉 11 并且文件在结尾
  • 我认为在类 unix 系统中,文本文件和二进制文件没有区别。
  • "我知道我应该用二进制模式打开文件。"就这样做吧。在 DOS/Windows 中,以文本模式打开的文件将 ASCII 26 (control-Z) 解释为文件结束标记,即使在 ASCII 标准中实际上并没有文件结束字符这样的东西。这是一个特定于操作系统的怪癖——几乎所有其他现代操作系统都不会这样做(尽管可能还有其他操作系统,所以我不会明确说明)......
  • @HesamQodsi 另一方面,我认为当您开发应用程序时, 您的工作是考虑该应用程序如何与任何环境交互的每一个细节(操作系统、库、框架、API 等)它会发现自己在其中运行......这将包括如何在该特定环境中正确打开和解析文件,以及大量其他细节......跨度>

标签: python windows file unix character


【解决方案1】:

问题出在窗户上。 0x1A 是 Ctrl-Z,DOS 使用它作为文件结束标记。 Python 使用 Windows CRT 函数 _wfopen,它实现了“Ctrl-Z 是 EOF”语义。 如果您的文件不是 128 字节的精确倍数,您需要一种方法来标记文本的结尾。 article 暗示 Ctrl-Z 的选择基于 DEC 使用的更老的约定。

【讨论】:

    【解决方案2】:

    这个暗号让我在 Windows 上打开和读取文件。此外,使用 curses,您可以获得文件中可能存在的任何控制字符的“^”表示。

    import curses.ascii
    
    filename = "myfile.txt"
    f = open(filename,"w")
    f.write("Hello\nWorld")
    f.write(chr(26)) # writing ascii character #26 to file 
    f.write("hhh")
    f.close()
    
    with open(filename,'r') as f:
        for line in f:
            line2 = [ curses.ascii.unctrl(c) if curses.ascii.iscntrl(c) else c for c in line]
            print("".join(line2))
    
    给出输出: 你好^J 世界^Zhh

    【讨论】:

    • 我认为您使用的是 Python 3?有趣的是,这意味着它们不再依赖底层 C 库来读取文件。
    • @MarkRansom:这可能与 Python 3 本机 str 类型为 Unicode 有关。由于字符现在是代码点而不是字节,因此不以特殊方式解释 U+001A 是有意义的。
    • 我今天又遇到了这个问题,并做了一些进一步的测试。 Python 3 确实不会在 26 日停止,我能够使用 latin-1 编码读取整个文件。即便如此,它确实将\r\n 转换为\n。如果我在 Python 2 中使用 codecs.open(..., 'r', encoding='latin-1'),它会像 Python 3 一样转换为 Unicode,但它不会在 26 处停止,但它也 转换 \r\n - 它就像一个二进制文件使用 Unicode 转换。
    • @MestreLion 它与 Unicode 无关,这只是 Windows 文本文件的传统约定。更有可能的是,由于 Python 3 允许进行重大更改,因此有人认为该约定已经过时,可以丢弃。
    猜你喜欢
    • 1970-01-01
    • 2012-04-21
    • 2015-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 2023-03-06
    • 2016-03-19
    相关资源
    最近更新 更多