在Matlab中读取labview二进制文件?

时间:2014-01-22 11:34:19

标签: matlab bigdata fread

我有大量的.bin文件(10GB-60GB),由Labview软件创建,.bin文件代表我用过的两个传感器的输出。

我遇到的问题是将数据导入Matlab,到目前为止我实现此目的的唯一方法是将.bin文件转换为Labview软件中的.txt文件,然后使用以下代码将数据导入MATLAB:

Nlines = 1e6; % set number of lines to sample per cycle
sample_rate = (1); %sample rate
DECE= 1000;% decimation factor

TIME = (0:sample_rate:sample_rate*((Nlines)-1));%first inctance of time vector
format = '%f\t%f';
fid = fopen('H:\PhD backup\Data/ONK_PP260_G_text.txt');

while(~feof(fid))

   C = textscan(fid, format, Nlines, 'CollectOutput', true);
   d = C{1};  % immediately clear C at this point you need the memory! 
   clearvars C ;
   TIME = ((TIME(end)+sample_rate):sample_rate:(sample_rate*(size(d,1)))+(TIME(end)));%shift Time along 
   plot((TIME(1:DECE:end)),(d(1:DECE:end,:)))%plot and decimate
   hold on;
   clearvars d;
end

fclose(fid);

我的代码背后的基本思想是通过将磁盘上的.txt数据的Nlines读取到RAM中的Matlab变量C,绘制C然后清除C来节省RAM。此过程在循环中进行,因此数据以块的形式绘制,直到到达.txt文件的末尾。

我想直接将.bin文件读入MATLAB,而不是先将它转换为.txt,因为转换完成需要几个小时,而且我有很多数据。以下是我的数据的一些示例,但是可管理的大小:

https://www.dropbox.com/sh/rzut4zbrert9fm0/q9SiZYmrdG

以下是二进制数据的说明: http://forums.ni.com/t5/LabVIEW/Loading-Labview-Binary-Data-into-Matlab/td-p/1107587

有人已准备好编写一个Matlab脚本来导入Labveiw .bin文件,但他们的脚本只适用于非常小的文件:

% LABVIEWLOAD  Load Labview binary data into Matlab
%
%   DATA = LABVIEWLOAD(FNAME,DIM); % Loads the Labview data in binary
%      format from the file specified by FNAME, given the NUMBER of 
%      dimensions (not the actual dimensions of the data in the binary 
%      file) of dimensions specified by DIM.
%
%      LABVIEWLOAD will repeatedly grab data until the end of the file.
%      Labview arrays of the same number of dimensions can be repeatedly 
%      appended to the same binary file.  Labview arrays of any dimensions
%      can be read.
%
%   DATA = LABVIEWLOAD(FNAME,DIM,PREC); % Loads the data with the specified
%      precision, PREC.
%
%   Note:  This script assumes the default parameters were used in the
%      Labview VI "Write to Binary File".  Labview uses the Big Endian
%      binary number format.
%
%   Examples:
%       D = labviewload('Data.bin',2);  % Loads in Data.bin assuming it
%          contains double precision data and two dimensions.
%
%       D = labviewload('OthereData.bin',3,'int8');  % Loads in
%          OtherData.bin assuming it contains 8 bit integer values or
%          boolean values.
%
% Jeremiah Smith
% 4/8/10
% Last Edit: 5/6/10

function data = labviewload(fname,dim,varargin)
siz = [2^32 2^16 2^8 1]';  % Array dimension conversion table

% Precision Input
if nargin == 2
    prec = 'double';
elseif nargin == 3
    prec = varargin{1};
else
    error('Too many inputs.')
end

%% Initialize Values
fid = fopen(fname,'r','ieee-be');  % Open for reading and set to big-endian binary format
fsize = dir(fname);  % File information
fsize = fsize.bytes;  % Files size in bytes

%% Preallocation
rows = [];
columns = [];
I = 0;
while fsize ~= ftell(fid)
    dims = [];
    for i=1:1:dim
        temp = fread(fid,4);
        temp = sum(siz.*temp);
        dims = [dims,temp];
    end
    I = I + 1;
%      fseek(fid,prod(dims)*8,'cof');  % Skip the actual data
    temp = fread(fid,prod(dims),prec,0,'ieee-be');  % Skip the actual data (much faster for some reason)
end
fseek(fid,0,'bof'); % Reset the cursor
data = repmat({NaN*ones(dims)},I,1);  % Preallocate space, assumes each section is the same

%% Load and parse data
for j=1:1:I
    dims = [];  % Actual array dimensions
    for i=1:1:dim
        temp = fread(fid,4);
        temp = sum(siz.*temp);
        dims = [dims,temp];
    end
    clear temp i

    temp = fread(fid,prod(dims),prec,0,'ieee-be');  % 11 is the values per row,
        % double is the data type, 0 is the bytes to skip, and
        % ieee-be specified big endian binary data

%% Reshape the data into the correct array configuration
    if dim == 1
        temp = reshape(temp,1,dims);
    else
        evalfunc = 'temp = reshape(temp';
        for i=1:1:dim
            evalfunc = [evalfunc ',' num2str(dims(dim-i+1))];
        end
        if dim ~= 2
            eval([evalfunc ');'])
        else
            eval([evalfunc ')'';'])
        end
    end

    data{j} = temp;  % Save the data
end

fclose(fid);  % Close the file

当您尝试处理甚至相对较小的.bin文件时,代码会出现以下错误消息:

Error using ones
Maximum variable size allowed by the program is exceeded.

Error in labviewload (line 65)
data = repmat({NaN*ones(dims)},I,1);  % Preallocate space, assumes each section is the same

你能帮我修改代码,以便我可以打开大的.bin文件吗?任何帮助将不胜感激。

干杯, 吉姆

0 个答案:

没有答案