0
所以,我创建使用MATLAB简单的二进制文件,该文件具有以下结构:读取预格式的二进制文件在Python
file.test
--------
[record_type] = 1 % 'int', 4 bytes, record_type = 1 means a string is read next
[string_length] = len(str) % 'int', 4 bytes, tells us how many bytes to read
[string] = '...' % 'char', the number of bytes in string length
[record_type] = 2 % 'int', 4 bytes, record_type = 2 means a vector will be read
[rows] = size(vector,1) % 'int', 4 bytes
[columns] = size(vector,2) % 'int', 4 bytes
[vector] = (vector) % 'double'
我可以在MATLAB用下面的代码读取该文件回(这是只是代码的读取部分,我有错误检查和其他东西):
fid=fopen('file.test','rb')
record_names={}
record_data=[]
while ~feof(fid)
[record_name_type,count]=fread(fid,1,'int');
if count == 0 % reached eof
break;
end
record_name_length=fread(fid,1,'int');
record_names{end+1}=char(fread(fid,record_name_length,'char')');
% read vector
record_type=fread(fid,1,'int');
rows=fread(fid,1,'int');
cols=fread(fid,1,'int');
record_data{end+1}=fread(fid,[rows,cols],'double');
end
所以,我不得不此相同的功能转化为Python 2.7版。不幸的是,这证明是非常困难的。我不能仅仅调用fread
并告诉它我想要读取多少个元素或字节。我曾尝试下面的代码与structs
:现在
def read_file(filename):
# checking to see if file exists/other checks happen
fid=open(filename,'rb')
record_data=[]
record_names=[]
result=read_record(fid)
while result:
record_names.append(result['record_name'])
record_names.append(result['data'])
result=read_record(fid)
fid.close()
return (record_names, record_data)
def read_record(fid):
try:
# read name
record_name_type = struct.unpack('i',fid.read(struct.calcsize('i')))[0]
record_name_len = struct.unpack('i',fid.read(struct.calcsize('i')))[0]
record_name = struct.unpack('s',fid.read(record_name_len))[0]
# read vector
record_type = struct.unpack('i',fid.read(struct.calcsize('i')))[0]
rows = struct.unpack('i',fid.read(struct.calcsize('i')))[0]
cols = struct.unpack('i',fid.read(struct.calcsize('i')))[0]
record_data = numpy.array(struct.unpack('%dd' % rows,fid.read(rows*struct.calcsize('d'))),dtype=float)
# store into result and return
result=OrderedDict()
result['record_name']=record_name
result['data']=record_data
except struct.error as e:
print e
result=None
return result
在Python运行我的方法的时候,我得到以下错误:
unpack requires a string argument of length 1
其从except strcut.error as e
部分即将到来。我有一种感觉,我错误地阅读矢量,但我不知道我是如何错误地阅读字符串。
有谁知道更简单的方法来阅读这个二进制文件?或者是否有一些教程可以帮助我理解如何在Python中正确使用结构?我真的很陌生,尤其是Python领域。
声明:'record_name = struct.unpack( 'S',fid.read(record_name_len))[0]'引起了例外。您应该在格式参数中指定字符串的长度:''%ds'%record_name_len'。 – acw1668
@ acw1668但是我怎么读它?做'record_name = struct.unpack('%ds'%record_name_len,fid.read(record_name_len))[0]'返回一个TypeError:解压期望的2个参数,得到3.'如果我只放入'record_name_len',它只知道使用'read()'?我有点困惑D: – Alex