2011-10-27 330 views
5

我通常在C++中執行類似這樣的操作,但是我使用python編寫了一個快速腳本,並且遇到了一堵牆。Python中,如何將32位整數放入字節數組中

如果我有一個二進制列表(或任何python存儲「fread」的結果)。我可以訪問其中的單個字節:緩衝區[0],緩衝區[1]等。

我需要更改字節[8-11]來保存新的32位文件大小(讀取:那裏已經有一個文件大小,我需要更新它)。在C++中,我只是得到一個指向該位置的指針並將其轉換爲存儲整數,但對於Python,我突然意識到我不知道如何做這樣的事情。

如何更新我的緩衝區中的特定位置的4個字節以保存python中的整數值?

編輯

我要添加更多的,因爲我似乎無法從解決方案看着辦吧(雖然我可以看到他們是在正確的軌道上)。

首先,我使用的是Python 2.4(無法升級,大公司服務器) - 這顯然限制了我的選擇。對不起,之前沒有提到,我不知道它有這麼多的功能。

其次,讓我們來做這個超簡單的。

假設我有一個名爲'myfile.binary'的二進制文件,其中包含十六進制的五字節內容'4C53535353' - 這等同於文件中單獨的字母「L和4xS」的ASCII表示。

如果我做的:

f = open('myfile.binary', 'rb') 
contents = f.read(5) 

內容應該(從斯文Marnach的答案)舉行的五字節的字符串不可改變。

只能使用Python 2.4的設施,我怎麼能把'內容'中保存的4個S更改爲任意整數值?即給我一行代碼,可以使字節索引的內容[1-4]包含值爲12345678910的32位整數'myint'。

+0

你不能因爲字符串修改內容是不變的...你可以創造吃了一個新的字符串,或者使用像bytearray這樣的可變容器。 – hochl

+0

謝謝,我很樂意創建一個新的字符串或字節數組,如果是這樣的話。我怎麼能創建一個可修改的字節數組與相同的contnets,並更新範圍[1-4],以等於我的整數的二進制表示? –

+0

我在下面擴展了我的發帖,幷包含了Python 2.4的一個工作示例:-) – hochl

回答

8

你需要的是這樣的功能:

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: How to pack different types of data into a string buffer using 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 
+1

+1。我建議使用內建的'bytearray'來創建可變緩衝區而不是'ctypes.create_string_buffer'。 –

+0

**對於所有人**,我嘗試閱讀包裝頁面和提供的解決方案。我似乎缺少很多,因爲我有python 2.4而不是2.5。我在編輯上提供了一個我的問題的大大簡化版本 - 如果你可以用一行代碼來回答,我會完全開心:) –

+1

恐怕你的2.4兼容版本不能使用' bytearray',因爲它是在2.6中引入的。 –

4

看看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個字節,我縮短了一下。

+0

*請參閱hochl的答案評論* –

+0

更新了答案 –

2

file.read()的結果是Python中的一個字符串,它是不可變的。根據您嘗試完成的任務的環境,有不同的解決方案。

一個使用的是array module:直接以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 
+1

*請參閱hochl的回答評論* –

2

你可以安裝numpy的模塊,經常用於科學計算。

的read_data = numpy.fromfile(文件= ID,D型= numpy.uint32)

然後在需要的位置訪問數據並進行更改。

+1

*請參閱hochl的回答評論* –

0

以下只是一個演示,用於瞭解將四個字節轉換爲整數時真正發生的情況。 假設有一個號碼:15213

Decimal: 15213 
Binary: 0011 1011 0110 1101 
Hex: 3 B 6 D 

在小端系統(即x86上),這個數字可以使用長度爲4字節組作爲表示:b"\x6d\x3b\x00\x00"b"m;\x00\x00"打印時在屏幕上,四個字節轉換爲整數,我們只是做了一下基轉換,在這種情況下,就是:

sum(n*(256**i) for i,n in enumerate(b"\x6d\x3b\x00\x00")) 

這給你一個結果:15213

相關問題