Python,如何将32位整数放入字节数组中
我通常在C++中这样做,但这次我用Python写一个快速脚本,结果遇到了一些问题。
如果我有一个二进制列表(或者说Python存储“fread”结果的方式),我可以通过:buffer[0]、buffer[1]等来访问其中的每个字节。
我需要把字节[8-11]改成一个新的32位文件大小(也就是说,那里已经有一个文件大小了,我需要更新它)。在C++中,我只需获取那个位置的指针,然后转换成整数来存储,但在Python中,我突然发现我不知道该怎么做。
我该如何在Python中更新缓冲区中特定位置的4个字节,使其存储一个整数的值呢?
补充说明
我想再补充一些,因为我似乎无法从已有的解决方案中搞明白(虽然我能看出它们在正确的方向上)。
首先,我用的是Python 2.4(而且不能升级,因为是大公司的服务器)——这显然限制了我的选择。抱歉之前没提到这一点,我没意识到它的功能少了这么多。
其次,让我们把问题简化一下。
假设我有一个名为'myfile.binary'的二进制文件,里面的内容是五个字节'4C53535353'(十六进制)——这对应于字母"L和4xS"的ASCII表示,文件里就只有这些。
如果我这样做:
f = open('myfile.binary', 'rb')
contents = f.read(5)
根据Sven Marnach的回答,内容应该包含一个五字节不可变字符串。
仅使用Python 2.4的功能,我该如何将'contents'中的4个S改成一个任意的整数值?也就是说,给我一行代码,让字节索引contents [1-4]包含值为12345678910的32位整数'myint'。
5 个回答
在Python中,file.read()
的结果是一个字符串,而字符串是不可改变的。根据你想完成的任务的不同,有不同的解决方案。
其中一种方法是使用array
模块:直接将文件读取为一个32位整数的数组。你可以修改这个数组,然后再把它写回文件。
with open("filename") as f:
f.seek(0, 2)
size = f.tell()
f.seek(0)
data = array.array("i")
assert data.itemsize == 4
data.fromfile(f, size // 4)
data[2] = new_value
# use data.tofile(g) to write the data back to a new file g
看看这个Struct模块。你需要用到pack
这个函数。
编辑:
代码如下:
import struct
s = "LSSSS" # your string
s = s[0] + struct.pack('<I', 1234567891) # note "shorter" constant than in your example
print s
输出结果:
L╙☻ЦI
struct.pack
在Python2.4版本中就可以使用了。
你的数字“12345678910”不能被压缩成4个字节,所以我把它缩短了一点。
你需要这个函数:
struct.pack_into(fmt, buffer, offset, v1, v2, ...)
相关文档可以在http://docs.python.org/library/struct.html的顶部找到。
示例代码:
import struct
import ctypes
data=ctypes.create_string_buffer(10)
struct.pack_into(">i", data, 5, 0x12345678)
print list(data)
类似的帖子: Python:如何使用struct.pack_into将不同类型的数据打包到字符串缓冲区中
编辑: 添加了一个兼容Python 2.4的示例:
import struct
f=open('myfile.binary', 'rb')
contents=f.read(5)
data=list(contents)
data[0:4]=struct.pack(">i", 0x12345678)
print data