2016-01-08 195 views
3

欲讀取數據的文件,以十六進制格式編碼:如何在Python中以二進制格式讀取二進制文件?

01ff0aa121221aff110120...etc 

文件含有> 100.000這樣字節,一些超過1,000,000(它們自帶型DNA測序)

我試圖下面的代碼(以及其他類似的):

filele=1234563 
f=open('data.geno','r') 
c=[] 
for i in range(filele): 
    a=f.read(1) 
    b=a.encode("hex") 
    c.append(b) 
f.close() 

這使每個字節單獨的「AA」「01」「F1」等,這是非常適合我!

這工作正常到(在這種情況下)字節號905碰巧是「1a」。我也嘗試了也停在同一個字節的ord()函數。

可能有一個簡單的解決方案?

+1

當你說停止了,你是否遇到異常,或者是什麼?另外要清楚的是,這是一個二進制文件,您想要讀取一系列十六進制編碼的字節值? –

+2

如果你正在閱讀一個二進制文件,最好使用''rb''作爲你的標誌來打開''。 – Turn

+0

我不能想出任何原因,假設你準確地呈現代碼,這會失敗。每個離散的字節值(和空字符串)編碼爲十六進制就好了(在Py2中,'十六進制'編解碼器已從Py3中的'str.encode'中移除)。對於每個可能的字符自己嘗試:'對於map(chr,range(256))中的c:print c.encode('hex')'。他們都工作。我的答案優化了C層的大部分工作(以換取稍高的峯值內存使用量),但是您的代碼不能以任何有意義的方式打破。請給出確切的例外或不當行爲。 – ShadowRanger

回答

7

簡單的解決方案是binascii

import binascii 

# Open in binary mode (so you don't read two byte line endings on Windows as one byte) 
# and use with statement (always do this to avoid leaked file descriptors, unflushed files) 
with open('data.geno', 'rb') as f: 
    # Slurp the whole file and efficiently convert it to hex all at once 
    hexdata = binascii.hexlify(f.read()) 

這只是讓你的十六進制值的str,但它確實比你想要做什麼快得多。如果你真的想了一堆長2串六角每個字節的,你可以將結果很容易地轉換:

hexlist = map(''.join, zip(hexdata[::2], hexdata[1::2])) 

這將產生LEN 2 str S的對應於每個字節的十六進制編碼的列表。爲了避免hexdata臨時副本,您可以使用使用相同的迭代器兩次zip避免切片相似但略有不足直觀的方法:

hexlist = map(''.join, zip(*[iter(hexdata)]*2)) 
1

如果該文件是十六進制格式編碼的,不應該每個字節用2個字符表示?所以

c=[] 
with open('data.geno','rb') as f: 
    b = f.read(2) 
    while b: 
     c.append(b.decode('hex')) 
     b=f.read(2) 
+0

這個問題的語法不明確,開篇也可能意味着「我想讀取數據並將其編碼爲十六進制」。問題的其餘部分指出他們需要兩個字符串,這有利於解釋。我承認這很混亂。 – ShadowRanger

+0

我用同樣的方法解答了這個問題。 +1 – SachaDee

0

感謝所有有趣的答案!

簡單的解決方案,它立即工作,是改變「R」爲「RB」, 這樣:

f=open('data.geno','r') # don't work 
f=open('data.geno','rb') # works fine 

在這種情況下,代碼實際上只有兩個二進制叮咬,所以一個字節包含四個數據,二進制; 00,01,10,11。

你的!