确保matlab的#fread`的python等价

时间:2015-12-01 17:25:47

标签: python matlab file

我在http://jmp.sh/VpTZxgQ找到了一个二进制测试文件,我试图在python中重写一些读取此文件的matlab代码。

我已经意识到matlab的fread会记住已经读取的内容,以便它跳过已经读取的字节数。我如何确保在python中获得相同的行为?

Matlab代码:

clear all; close all;

path = pwd;
ext = 'bin';
stem = 'test';
filename = [stem,'.',ext];
filename = fullfile(path,filename);
fid = fopen(filename,'r');

fread(fid,2,'int16')
fread(fid,32,'char')
fread(fid,2,'int16')

Python代码:

import numpy as np  

def fread(filename, n, precision):
     with open(filename, 'rb') as fid:
         data_array = np.fromfile(fid, precision).reshape((-1, 1)).T

     return data_array[0,0:n]

print fread('test.bin', 2, np.int16)                                                                                                                         
print fread('test.bin', 32, np.str)
print fread('test.bin', 2, np.int16) 

理想情况下,我希望这些配方的输出相同,但它们不是。实际上,当我尝试将value error设置为precision时,python会给出np.str ...

作为一个额外的问题 - 我假设读取二进制文件并理解数据需要用户了解数据的格式,以便提供数据的任何合理信息。这是真的吗?

1 个答案:

答案 0 :(得分:4)

正如评论所示,您需要使用文件描述符,这是Matlab代码正在做的事情:

import numpy as np

def fread(fid, nelements, dtype):
     if dtype is np.str:
         dt = np.uint8  # WARNING: assuming 8-bit ASCII for np.str!
     else:
         dt = dtype

     data_array = np.fromfile(fid, dt, nelements)
     data_array.shape = (nelements, 1)

     return data_array

fid = open('test.bin', 'rb');

print fread(fid, 2, np.int16)
print fread(fid, 32, np.str)
print fread(fid, 2, np.int16)

阅读&将数据写入二进制文件需要读写器就指定的格式达成一致。正如评论者所说,如果您将二进制文件保存在一台计算机上并尝试在另一台计算机上阅读,那么endianess可能会成为一个问题。如果始终在同一个CPU上写入和读取数据,那么您将不会遇到此问题。

test.bin的输出:

MATLAB Output             Python+Numpy Output
------------------------------------------------------
ans =                     

    32                    [[32]
     0                     [ 0]]

ans =                   

    35                    [[ 35]
    32                     [ 32]
    97                     [ 97]
   102                     [102]
    48                     [ 48]
    52                     [ 52]
    50                     [ 50]
    95                     [ 95]
    53                     [ 53]
    48                     [ 48]
   112                     [112]
   101                     [101]
   114                     [114]
    99                     [ 99]
    95                     [ 95]
   115                     [115]
   112                     [112]
    97                     [ 97]
   110                     [110]
    32                     [ 32]
    32                     [ 32]
    32                     [ 32]
    32                     [ 32]
    32                     [ 32]
    32                     [ 32]
    32                     [ 32]
    32                     [ 32]
    32                     [ 32]
    32                     [ 32]
    32                     [ 32]
    32                     [ 32]
    32                     [ 32]]

ans =

    32                     [[32]
     0                      [ 0]]