gpt4 book ai didi

python - 如果我将两种编码字符串(例如 utf-8 和 utf-16)放在一个文件中会怎么样?

转载 作者:太空宇宙 更新时间:2023-11-03 13:50:02 25 4
gpt4 key购买 nike

例如,在 Python 中:

f = open('test','w')
f.write('this is a test\n'.encode('utf-16'))
f.write('another test\n'.encode('utf-8'))
f.close()

当我重新打开时,该文件变得困惑:

f = open("test")
print f.readline().decode('utf-16') # it leads to UnicodeDecodeError
print f.readline().decode('utf-8') # it works fine

但是,如果我将文本以一种样式编码(仅比如 utf-16),它可以正常读取。所以我猜想在同一个文件中混合两种类型的编码是错误的并且无法解码回来,即使我确实知道每个特定字符串的编码规则?欢迎任何建议,谢谢!

最佳答案

这通常是个坏主意,但在您的情况下它不起作用,因为您也对换行符进行了编码。

在 UTF-16 中,每个 字符都被编码为两个字节,包括您编写的换行符。因为您逐行读取文件,python 将为您提供从文件到下一个换行字节的所有数据,但在 UTF-16 中,这可能意味着返回的数据中仍包含两个字节之一,从而导致不完整UTF-16字节流。

要理解这一点,您需要更详细地了解 UTF-16 编码。当将16位数据写成2个字节的8位数据时,计算机需要决定先将哪个字节写入文件。这个决定可以有两种方式,称为 endianess ;就像格列佛的小人国一样,计算机系统更喜欢大端或小端排序。

UTF-16 数据流因此以两种顺序之一写入,并且 Byte Order Mark或先写“BOM”以标记选择了哪个。

因此,您的换行符被编码为 '\n\x00''\x00\n',并且在读取该空字节 (\x00 ) 是您解码的 UTF-16 数据的一部分,或者是 UTF-8 数据(被忽略的地方)。因此,如果您将 UTF-16 编码为大端,一切正常(但您有一个杂散的空字节),但如果您编码为小端,则一切都会崩溃。

基本上,编码数据应该被严格地视为二进制数据,您应该使用不同的方法来描述不同的编码文本片段,或者您应该只使用将换行符严格编码为换行符的编码。

我会使用一个长度前缀,首先读取它,然后从文件中读取每个编码数据片段的字节数。

>>> import struct
>>> f = open('test', 'wb')
>>> entry1 = 'this is a test\n'.encode('utf-16')
>>> struct.pack('!h', len(entry1)))
>>> f.write(entry1)
>>> entry2 = 'another test\n'.encode('utf-8')
>>> f.write(struct.pack('!h', len(entry2)))
>>> f.write(entry2)
>>> f.close()

我用过 struct module写入固定长度的数据。请注意,我也将文件写为二进制文件。

阅读:

>>> f = open('test', 'rb')
>>> fieldsize = struct.calcsize('!h')
>>> length = struct.unpack('!h', f.read(fieldsize))[0]
>>> print f.read(length).decode('utf-16')
this is a test

>>> length = struct.unpack('!h', f.read(fieldsize))[0]
>>> print f.read(length).decode('utf-8')
another test

>>>

文件再次以二进制模式打开。

在实际应用程序中,您可能还必须包含每个条目的编码信息。

关于python - 如果我将两种编码字符串(例如 utf-8 和 utf-16)放在一个文件中会怎么样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11114720/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com