如何将字节追加到字符串?

3 投票
4 回答
22628 浏览
提问于 2025-04-17 16:19

我在Python中打开了一个文件,并打算把内容写入另一个输出文件。我需要这个输出文件的大小是16的倍数,所以我想了一个办法:

 with open(input_file, 'rb') as infile:
     with open(output_file, 'wb') as outfile:
         while True:
             input_chunk = infile.read(64)

             if len(input_chunk) == 0:
                 break
             elif len(input_chunk) % 16 > 0:
                 input_chunk.extend([0 for i in range(len(input_chunk) % 16)])

             output_file.write(input_chunk)

不过,这个办法在添加零的时候失败了,出现了:

AttributeError: 'str' object has no attribute 'extend'

首先,为什么我这里得到的是一个字符串,而不是字节数组呢?我明明是以二进制模式读取的文件。

其次,如果我处理的是一个字符串,那我该怎么把值为0的字节写到这个字符串的末尾呢?

4 个回答

1

你只需要用 bytearray 就可以了,这样就没问题了:

           input_chunk = bytearray(infile.read(64))

不过我建议用 [0] * (16 - len(input_chunk)%16) 来处理填充,而不是用列表推导式。

4

在Python 2.x中,str对象可以看作是一个“字节数组”。

如果你需要一个可以改变内容的数组,可以在2.6及以上版本中使用bytearray:

>>> a = bytearray('my_string')
>>> a.extend(' hello')
>>> str(a)
'my_string hello'

否则的话:

>>> import array
>>> a = array.array('c', 'my_string')
5

首先,为什么我这里有一个字符串,而不是一个字节数组呢?

因为这就是file.read返回的结果……

其次,如果我在处理一个字符串,怎么把值为0的多个字节写到这个字符串的末尾呢?

你不能直接把它写到这个字符串上,因为字符串是不可变的。不过,你可以把它写到另一个字符串上,通过拼接来创建新的字符串:

>>> import struct
>>> input_chunk = 'foo bar baz'
>>> input_chunk + struct.pack('16B',*([0]*16))
'foo bar baz\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> 

注意,如果你知道你有64个字节,而你想要一个填充了空字节的80字节字符串,struct.pack 会自动用空字节填充它

struct.pack('80s',string_of_64_bytes)

对于's'格式字符,计数被解释为字符串的大小,而不是像其他格式字符那样的重复计数;例如,'10s'表示一个10字节的字符串,而'10c'表示10个字符。如果没有给出计数,默认值是1。对于打包,字符串会被截断或用空字节填充,以适应大小。对于解包,结果字符串总是恰好有指定的字节数。作为一个特例,'0s'表示一个空字符串(而'0c'表示0个字符)。

撰写回答