确保matlab的`fread`的python等效

Dip*_*ole 3 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')
Run Code Online (Sandbox Code Playgroud)

蟒蛇代码:

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) 
Run Code Online (Sandbox Code Playgroud)

理想情况下,我希望这些公式的输出相同,但事实并非如此。事实上蟒蛇给人value error当我尝试设置precision到np.str...

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

Nic*_*ick 5

正如评论所暗示的那样,您需要使用文件描述符,这就是 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)
Run Code Online (Sandbox Code Playgroud)

以二进制形式将数据读取和写入文件需要读取器和写入器就指定的格式达成一致。正如评论者所建议的那样,如果您将二进制文件保存在一台计算机上并尝试在另一台计算机上读取它,则字节顺序可能会成为一个问题。如果数据总是在同一个 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]]
Run Code Online (Sandbox Code Playgroud)