3

さまざまな種類のバイナリ データを含むファイルがいくつかあり、これらのファイルを処理するモジュールを作成しています。

とりわけ、次の形式の UTF-8 でエンコードされた文字列が含まれてます。UTF-8 であるため、文字列のバイト単位の長さはstringLengthよりも大きくなる可能性があり、文字列にマルチバイト文字が含まれている場合、read(stringLength) を実行すると短くなります (ファイル内の他のすべてのデータが台無しになることは言うまでもありません)。 .

UTF-8のマルチバイト プロパティを認識しながら、ファイルからn 個の UTF-8 文字 (nバイトとは異なる)を読み取るにはどうすればよいですか? 私は 30 分間グーグル検索してきましたが、見つけたすべての結果は関連性がないか、私にはできない仮定をしています。

4

2 に答える 2

6

ファイルオブジェクトといくつかの文字を指定すると、次を使用できます。

# build a table mapping lead byte to expected follow-byte count
# bytes 00-BF have 0 follow bytes, F5-FF is not legal UTF8
# C0-DF: 1, E0-EF: 2 and F0-F4: 3 follow bytes.
# leave F5-FF set to 0 to minimize reading broken data.
_lead_byte_to_count = []
for i in range(256):
    _lead_byte_to_count.append(
        1 + (i >= 0xe0) + (i >= 0xf0) if 0xbf < i < 0xf5 else 0)

def readUTF8(f, count):
    """Read `count` UTF-8 bytes from file `f`, return as unicode"""
    # Assumes UTF-8 data is valid; leaves it up to the `.decode()` call to validate
    res = []
    while count:
        count -= 1
        lead = f.read(1)
        res.append(lead)
        readcount = _lead_byte_to_count[ord(lead)]
        if readcount:
            res.append(f.read(readcount))
    return (''.join(res)).decode('utf8')

テストの結果:

>>> test = StringIO(u'This is a test containing Unicode data: \ua000'.encode('utf8'))
>>> readUTF8(test, 41)
u'This is a test containing Unicode data: \ua000'

もちろん、Python 3 では、ファイル オブジェクトをオブジェクトでラップし、デコードをネイティブで効率的な Python UTF-8 実装に任せる方がはるかに簡単です。io.TextIOWrapper()

于 2013-03-04T11:23:19.160 に答える
0

UTF-8の1文字は、1byte、2bytes、3byte3です。

ファイルをバイトごとに読み取る必要がある場合は、UTF-8エンコード規則に従う必要があります。 http://en.wikipedia.org/wiki/UTF-8

ほとんどの場合、エンコーディングをutf-8に設定して、入力ストリームを読み取ることができます。

読み取ったバイト数を気にする必要はありません。

于 2013-03-04T10:51:30.973 に答える