将字节和字符串写入文件

3

我需要创建一些带有字符和十六进制值的小端编码文件。为进行编码,我使用以下方法:

pack("I", 0x01ddf23a)

而这给了我:
b':\xf2\xdd\x01'

第一个问题是,这给了我字节字符串,但我无法将其写入文件。第二个问题是\x3a被转换为“:”。我期望的是将\x3a\xf2\xdd\x01作为字节写入文件,而不是作为字符。

我尝试过:

>>> a=0x01ddf23a

>>> str(pack("I", a))
"b':\\xf2\\xdd\\x01'" <= wrong

>>> pack("I", a).hex()
'3af2dd01             <= I need '\x' before each byte

>>> pack("I", a).decode()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf2 in position 1: invalid continuation byte

将open()中的"w"更改为"wb"会强制我只能写入字节,但是我想写入许多字符串和少量字节,例如:
Hello world
^I^M^T^B
End file

我知道我可以简单地做到这一点:

fs.open("file" "w")
fs.write("Hello world")
fs.write("\x3a\xf2\xdd\x01")
fs.write("End file")
fs.close()

但是这会使我的字节值0x01ddf23a难以阅读,且在更改此值时很容易犯错。

1个回答

6

你正在生成字节,可以在以二进制模式打开的文件中无问题地写入。打开文件时,在文件模式中添加b,并且如果需要写入其他数据,则使用bytes字符串文本或将字符串编码为字节:

with open("file", "wb") as fs:
    fs.write(b"Hello world")  # note, a byte literal!
    fs.write(pack("I", 0x01ddf23a))
    fs.write("End file".encode('ASCII'))  # encoded string to bytes

另一种选择是先将您的二进制打包数据解码为文本字符串,但由于打包数据实际上并不包含可解码的文本,因此该方法需要扭曲以强制使二进制数据可以再次解码和编码,只有在文件编码设置为Latin-1时才能使用,并且严重限制了您可以添加的实际文本。

bytes表示将始终尝试显示可打印字符。 字节\x3a也是':'字符的正确ASCII值,因此在bytes表示中,后者优于使用\x3a转义序列。 正确的值存在于bytes值中,并将完全正确地写入文件:

>>> b'\x3a'
b':'
>>> b'\x3a' == b':'
True
>>> b':'[0]
58
>>> b'\x3a'[0]
58
>>> hex(58)
'0x3a'

太完美了!正是我需要的 :) 首先,使用字节字符串文字与二进制模式下的文件非常简单,其次,很好地解释了如果Python在字节字符串文字中显示一些ASCII字符,并不意味着它会将这些ASCII字符打印出来。 - Borgo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接