我想读取一个包含数据的文件,以十六进制格式编码:
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”等,这对我来说是完美的!
这可以正常工作(在这种情况下)字节no 905碰巧是“1a”。我也尝试了在同一个字节停止的ord()函数。
可能有一个简单的解决方案?
答案 0 :(得分:11)
简单的解决方案是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
列表。为了避免hexdata
的临时副本,您可以使用类似但稍微不那么直观的方法,通过使用zip
两次使用相同的迭代器来避免切片:
hexlist = map(''.join, zip(*[iter(hexdata)]*2))
<强>更新强>
对于Python 3.5及更高版本的人bytes
objects spawned a .hex()
method,因此不需要模块将原始二进制数据转换为ASCII十六进制。顶部的代码块可以简化为:
with open('data.geno', 'rb') as f:
hexdata = f.read().hex()
答案 1 :(得分: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)
答案 2 :(得分:1)
仅需补充说明,请确保在文件的.read中添加一个中断,否则它将继续运行。
def HexView():
with open(<yourfilehere>, 'rb') as in_file:
while True:
hexdata = in_file.read(16).hex() # I like to read 16 bytes in then new line it.
if len(hexdata) == 0: # breaks loop once no more binary data is read
break
print(hexdata.upper()) # I also like it all in caps.
答案 3 :(得分:0)
感谢所有有趣的答案!
立即起作用的简单解决方案是将“r”改为“rb”, 这样:
f=open('data.geno','r') # don't work
f=open('data.geno','rb') # works fine
这种情况下的代码实际上只有两个二进制位,所以一个字节包含四个数据,二进制; 00,01,10,11。
此致!