我写了一个python脚本来创建一个整数的二进制文件.
import struct
pos = [7623, 3015, 3231, 3829]
inh = open('test.bin', 'wb')
for e in pos:
inh.write(struct.pack('i', e))
inh.close()
Run Code Online (Sandbox Code Playgroud)
它工作得很好,然后我尝试使用下面的代码读取'test.bin'文件.
import struct
inh = open('test.bin', 'rb')
for rec in inh:
pos = struct.unpack('i', rec)
print pos
inh.close()
Run Code Online (Sandbox Code Playgroud)
但它失败并显示错误消息:
Traceback (most recent call last):
File "readbinary.py", line 10, in <module>
pos = struct.unpack('i', rec)
File "/usr/lib/python2.5/struct.py", line 87, in unpack
return o.unpack(s)
struct.error: unpack requires a string argument of length 4
Run Code Online (Sandbox Code Playgroud)
我想知道如何使用这些文件阅读struct.unpack.
非常感谢,Vipin
for rec in inh:一次读取一行 - 不是您想要的二进制文件.改为一次读取4个字节(使用while循环和inh.read(4))(或者通过一次.read()调用将所有内容读入内存,然后解压缩连续的4字节切片).第二种方法最简单,最实用,只要涉及的数据量不大:
import struct
with open('test.bin', 'rb') as inh:
indata = inh.read()
for i in range(0, len(data), 4):
pos = struct.unpack('i', data[i:i+4])
print(pos)
Run Code Online (Sandbox Code Playgroud)
如果您确实害怕潜在的大量数据(这将占用比您可用的更多的内存),一个简单的生成器提供了一个优雅的替代方案:
import struct
def by4(f):
rec = 'x' # placeholder for the `while`
while rec:
rec = f.read(4)
if rec: yield rec
with open('test.bin', 'rb') as inh:
for rec in by4(inh):
pos = struct.unpack('i', rec)
print(pos)
Run Code Online (Sandbox Code Playgroud)
第二种方法的一个关键优势是by4可以轻松调整生成器(同时保持规范:一次返回二进制文件的4个字节数据),以使用不同的实现策略进行缓冲,一直到第一种方法(读取)然后把所有东西包裹起来)可以看作"无限缓冲"并编码:
def by4(f):
data = inf.read()
for i in range(0, len(data), 4):
yield data[i:i+4]
Run Code Online (Sandbox Code Playgroud)
同时留下了"应用逻辑"(什么做具有4个字节的组块流)完整和独立的I/O层(其被所述发电机内封装的).
我认为“ for rec in inh”应该读取“行”,而不是字节。您想要的是:
while True:
rec = inh.read(4) # Or inh.read(struct.calcsize('i'))
if len(rec) != 4:
break
(pos,) = struct.unpack('i', rec)
print pos
Run Code Online (Sandbox Code Playgroud)
或者像其他人提到的那样:
while True:
try:
(pos,) = struct.unpack_from('i', inh)
except (some_exception...):
break
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13833 次 |
| 最近记录: |