【问题标题】:Does reading a binary file linewise in python cause problems for unicode data?在 python 中逐行读取二进制文件是否会导致 unicode 数据出现问题?
【发布时间】:2019-05-26 18:39:45
【问题描述】:

我正在 python3 中读取一个大 (10Gb) bzipped 文件,它是 utf-8 编码的 JSON。不过,我只想要几行,它们以特定的字节集开头,所以为了省去将所有行解码为 un​​icode 的麻烦,我正在以 'rb' 模式读取文件,如下所示:

with bz2.open(filename, 'rb') as file:
    for line in file:
        if line.startswith(b'Hello'):
            #decode line here, then do stuff

但我突然想到,如果其中一个 unicode 字符包含与换行符相同的字节怎么办?通过for line in file 我会冒被截断行的风险吗?或者二进制文件上的逐行迭代器仍然可以魔术吗?

【问题讨论】:

  • 顺便说一句,除了我的回答:codecs.iterdecode 函数可能与您的用例相关,因为您似乎关心处理速度。我从未对它进行基准测试,但我想与line.decode('utf8') 相比,它可能会节省一些开销。将现有代码包装在生成器函数中,并将其作为第一个参数传递给 iterdecode()

标签: python-3.x unicode newline filehandle


【解决方案1】:

逐行迭代适用于 UTF-8 编码数据。 不是魔术,而是设计: 创建 UTF-8 是为了向后兼容 ASCII。

ASCII 仅使用 0 到 127 的字节值,将可能值的上半部分用于任何类型的扩展。 UTF-8 利用了这一点,因为 ASCII 之外的任何 Unicode 代码点都使用 128..255 范围内的字节进行编码。

例如,字母“Ċ”(上面带有点的大写字母 C)具有 Unicode 代码点值 U+010A。 在 UTF-8 中,这是用字节序列 C4 8A 编码的,因此不使用字节 0A,它是 ASCII 换行符。

相比之下,UTF-16 编码与0A 0101 0A 相同的字符(取决于字节序)。 所以我猜 UTF-16 不安全地进行逐行迭代。 不过,它不像文件编码那么常见。

【讨论】:

    猜你喜欢
    • 2011-01-07
    • 2011-07-17
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    相关资源
    最近更新 更多