我正在尝试在 Python 中读取一个二进制文件(它代表 Matlab 中的矩阵)。
但是我无法读取文件并将字节转换为正确的值。
二进制文件由一系列 4 字节的数字组成。前两个数字分别是行数和列数。我的 friend 给了我一个他编写的 Matlab 函数,该函数使用 fwrite 执行此操作。
我想做这样的事情:
f = open(filename, 'rb')
rows = f.read(4)
cols = f.read(4)
m = [[0 for c in cols] for r in rows]
r = c = 0
while True:
if c == cols:
r += 1
c = 0
num = f.read(4)
if num:
m[r][c] = num
c += 1
else:
break
但是每当我使用 f.read(4) 时,我都会得到类似 '\x00\x00\x00\x04' 的结果(这个特定的例子应该代表一个 4),我无法弄清楚将它转换成正确的数字(使用int、hex 或任何类似的东西都不起作用)。我偶然发现了 struct.unpack,但这似乎没有多大帮助。
这是一个示例矩阵和 Matlab 函数为其创建的相应二进制文件(当我使用没有任何大小参数的 python 函数 f.read() 读取整个文件时出现的):
4 4 2 4
2 2 2 1
3 3 2 4
2 2 6 2
'\x00\x00\x00\x04\x00\x00\x00\x04@\x80\x00\x00@\x00\x00\x00@@\x00\x00@\x00\x00\x00@\x80\x00\x00@\x00\x00\x00@@\x00\x00@\x00\x00\x00@\x00\x00\x00@\x00\x00\x00@\x00\x00\x00@\xc0\x00\x00@\x80\x00\x00?\x80\x00\x00@\x80\x00\x00@\x00\x00\x00'
所以前 4 个字节和第 5-8 个字节都应该是 4,因为矩阵是 4x4。然后它应该是 4,4,2,4,2,2,2,1 等...
谢谢你们!
最佳答案
我在你的问题中看了更多,因为我以前从未使用过 struct
,所以这是很好的学习事件。事实证明,那里有一些曲折——首先,数字不是存储为 4 字节整数,而是存储为大端格式的 4 字节浮点数。其次,如果你的例子是正确的,那么矩阵不是按预期存储的——按行,而是按列。例如。它是这样输出的(伪代码):
for j in cols:
for i in rows:
write Aij to file
所以我不得不在阅读后转置结果。以下是示例所需的代码:
import struct
def readMatrix(f):
rows, cols = struct.unpack('>ii',f.read(8))
m = [ list(struct.unpack('>%df' % rows, f.read(4*rows)))
for c in range(cols)
]
# transpose result to return
return zip(*m)
在这里我们测试一下:
>>> from StringIO import StringIO
>>> f = StringIO('\x00\x00\x00\x04\x00\x00\x00\x04@\x80\x00\x00@\x00\x00\x00@@\x00\x00@\x00\x00\x00@\x80\x00\x00@\x00\x00\x00@@\x00\x00@\x00\x00\x00@\x00\x00\x00@\x00\x00\x00@\x00\x00\x00@\xc0\x00\x00@\x80\x00\x00?\x80\x00\x00@\x80\x00\x00@\x00\x00\x00')
>>> mat = readMatrix(f)
>>> for row in mat:
... print row
...
(4.0, 4.0, 2.0, 4.0)
(2.0, 2.0, 2.0, 1.0)
(3.0, 3.0, 2.0, 4.0)
(2.0, 2.0, 6.0, 2.0)
关于Python二进制文件读取问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3162191/