【问题标题】:Read utf-8 character from byte stream从字节流中读取 utf-8 字符
【发布时间】:2015-07-26 14:13:07
【问题描述】:

给定一个字节流(生成器、文件等),我如何读取单个 utf-8 编码字符?

  • 此操作必须从流中消耗该字符的字节。
  • 此操作不得消耗超过第一个字符的流中的任何字节。
  • 此操作应在任何 Unicode 字符上成功。

我可以通过滚动我自己的 utf-8 解码函数来解决这个问题,但我不希望重新发明轮子,因为我确信这个功能必须已经在其他地方用于解析 utf-8 字符串。

【问题讨论】:

    标签: python-3.x utf-8 utf8-decode


    【解决方案1】:

    使用encoding='utf8' 将流包装在TextIOWrapper 中,然后在其上调用.read(1)

    这是假设您从 BufferedIOBase 或与之兼容的鸭子类型开始(即具有 read() 方法)。如果您有生成器或迭代器,则可能需要调整接口。

    例子:

    from io import TextIOWrapper
    
    with open('/path/to/file', 'rb') as f:
      wf = TextIOWrapper(f, 'utf-8')
      wf._CHUNK_SIZE = 1  # Implementation detail, may not work everywhere
    
      wf.read(1) # gives next utf-8 encoded character
      f.read(1)  # gives next byte
    

    【讨论】:

    • TextIOWrapper 是否进行任何缓冲(从而消耗超过第一个字符的字节)?如果我获取一个文件f 并将其包装wrapped = TextIOWrapper(f, 'utf-8'),则调用wrapper.read(1) 后跟f.read(1) 会读取比紧跟在utf-8 字符后面的字节更远的字节。
    • @arcyqwerty:TextIOWrapper 一次读取 2k 字节 (_CHUNK_SIZE)。它消耗的字节数超过了第一个字符所需的字节数。
    • 或者,有没有办法从包装器 TextIOWrapper 获取原始字节?
    • 在这种情况下,它似乎违反了This operation must not consume any bytes of the stream that exceed the first character. 是否有禁用缓冲的解决方法?
    • @arcyqwerty: 设置_CHUNK_SIZE=1?
    猜你喜欢
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 2017-02-04
    • 1970-01-01
    • 2018-06-18
    相关资源
    最近更新 更多