3

我有一个在 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

4 回答 4

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')
于 2013-02-19T04:20:19.623 回答
4

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

因为这就是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 个字符)。

于 2013-02-19T04:20:54.620 回答
1

只需使用bytearray,您就应该保持原样:

           input_chunk = bytearray(infile.read(64))

虽然我只会使用类似的东西[0] * (16 - len(input_chunk)%16)而不是填充的列表理解。

于 2013-02-19T04:26:05.283 回答
0

你可以input_chunk像这样填充你的

input_chunk += '\x00'*(-len(input_chunk)%16)
于 2013-02-19T04:42:51.800 回答