【发布时间】:2016-12-26 01:24:04
【问题描述】:
所以,我使用 MATLAB 创建了一个简单的二进制文件,其结构如下:
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 但是我该如何阅读呢?执行
record_name = struct.unpack('%ds' % record_name_len,fid.read(record_name_len))[0]会返回TypeError: unpack expected 2 arguments, got 3.如果我只在其中输入record_name_len,它是否只知道使用read()?我有点困惑 D:
标签: python matlab file numpy binary