big endianファイルの読み書き

FIFFファイルはbig endianで書かれたbinary dataの構造体のファイルです。 そのままではMATLABで読み込むことはできません。 そこでいくつかの関数を組み合わせて読む必要があります。 uint8で一旦符号なし1 byteの整数として読みこみ、swapbytesとtypecastを組み合わせます。 サンプルを提示します。

Contents

big endianファイルの作成・書き出し

Matlabではfreadやfwrite関数で'ieee-be'を指定すればbig endianで読み書きできます。 固有の構造体になっている場合には話は面倒になります。 特に一旦全部読み込んで、そのメモリ上で構造体を決定する場合には'ieee-be'の手法は使えません。

% 通常の方法
x=single(rand(1,16));% 4 byte浮動小数点からなる1x16の行列作成
fid=fopen('sample1.bin','wb');
fwrite(fid,x,'single','ieee-be');
fclose(fid);
% メモリ上で展開する方法
y=swapbytes(x);% little endianからbig endianに変換
z=typecast(y,'uint8');% 4 byte浮動小数点を1byteの整数に変換
fid=fopen('sample2.bin','wb');
fwrite(fid,z,'uint8');
fclose(fid);

big endianファイルの読み込み

通常の方法

fid=fopen('sample1.bin','rb');
x1=fread(fid,[1,16],'single','ieee-be');
fclose(fid);
max(abs(x-x1))% 検算
fid=fopen('sample2.bin','rb');
x2=fread(fid,[1,16],'single','ieee-be');
fclose(fid);
max(abs(x-x2))% 検算
% メモリ上で展開する方法
fid=fopen('sample1.bin','rb');
B=fread(fid,'*uint8');
fclose(fid);
x3=typecast(B,'single')';%転置
x3=swapbytes(x3);
max(abs(x-x3))%検算
ans =

  single

     0


ans =

  single

     0


ans =

  single

     0

構造体のメンバの数が不明な場合

チャンネル数や時系列データの大きさは任意です。 構造体にするとメンバの数が不明ということになります。

% データ作成
clear;
F=[];
for n=1:10
    F.data{n}.x=int32(n);
    F.data{n}.y=rand(1,3);
    F.data{n}.z=single(rand(3,3));
end

% データ書き込み
fid=fopen('sample3.bin','wb');
for n=1:10
    fwrite(fid,F.data{n}.x,'int32','ieee-be');
    fwrite(fid,F.data{n}.y,'double','ieee-be');
    fwrite(fid,F.data{n}.z,'single','ieee-be');
end
fclose(fid);

% 読み込み
fid=fopen('sample3.bin','rb');
B=fread(fid,'*uint8');
fclose(fid);
G=[];
address=0;
n=1;
while address<length(B)
    try
        x=swapbytes(typecast(B(address+(1:4)),'int32'));
        address=address+4;
        y=swapbytes(typecast(B(address+(1:24)),'double'));
        y=reshape(y,[1,3]);
        address=address+24;
        z=swapbytes(typecast(B(address+(1:36)),'single'));
        z=reshape(z,[3,3]);
        address=address+36;
    catch
        break;
    end
    data.x=x;
    data.y=y;
    data.z=z;
    if ~isfield(G,'data')
        G.data=data;
    else
        if isa(G.data,'cell')
            G.data{end+1}=data;
        else
            xx=G.data;
            G=rmfield(G,'data');
            G.data{1}=xx;
            G.data{2}=data;
        end
    end
end
% 検算
check=0;
for n=1:length(F.data)
   if all(F.data{n}.x-G.data{n}.x)
       fprintf('G.data{%d}.x is error\n',n);
       check=1;
   end
   if all(F.data{n}.y-G.data{n}.y)
       fprintf('G.data{%d}.y is error\n',n);
       check=1;
   end
   if all(F.data{n}.z-G.data{n}.z)
       fprintf('G.data{%d}.z is error\n',n);
       check=1;
   end
   if check==0
       fprintf('G.data{%d} is eqivalent to F.data{%d}\n',n,n);
   end
end
G.data{1} is eqivalent to F.data{1}
G.data{2} is eqivalent to F.data{2}
G.data{3} is eqivalent to F.data{3}
G.data{4} is eqivalent to F.data{4}
G.data{5} is eqivalent to F.data{5}
G.data{6} is eqivalent to F.data{6}
G.data{7} is eqivalent to F.data{7}
G.data{8} is eqivalent to F.data{8}
G.data{9} is eqivalent to F.data{9}
G.data{10} is eqivalent to F.data{10}