リクエストに応じて、クラスを使用したメモリ マップトファイルの例を示します。memmapfile
データ ファイルの正確な形式が提供されていないため、独自の形式を作成します。私が作成しているデータはN
、それぞれが 4 つの列で構成される行のテーブルです。
- 最初は
double
スカラー値です
- 秒は
single
値です
uint32
3 番目は、 HEX 表記でa を表す固定長の文字列です(例: D091BB44
)
- 4列目は
uint8
値です
ランダム データを生成し、上記の構造のバイナリ ファイルに書き込むコード:
% random data
N = 10;
data = [...
num2cell(rand(N,1)), ...
num2cell(rand(N,1,'single')), ...
cellstr(dec2hex(randi(intmax('uint32'), [N,1]),8)), ...
num2cell(randi([0 255], [N,1], 'uint8')) ...
];
% write to binary file
fid = fopen('file.bin', 'wb');
for i=1:N
fwrite(fid, data{i,1}, 'double');
fwrite(fid, data{i,2}, 'single');
fwrite(fid, data{i,3}, 'char');
fwrite(fid, data{i,4}, 'uint8');
end
fclose(fid);
HEX エディタで表示した結果のファイルを次に示します。
最初のレコードを確認できます (私のシステムはリトル エンディアンのバイト順を使用していることに注意してください)。
>> num2hex(data{1,1})
ans =
3fd4d780d56f2ca6
>> num2hex(data{1,2})
ans =
3ddd473e
>> arrayfun(@dec2hex, double(data{1,3}), 'UniformOutput',false)
ans =
'46' '35' '36' '32' '37' '35' '32' '46'
>> dec2hex(data{1,4})
ans =
C0
次に、メモリ マッピングを使用してファイルを開きます。
m = memmapfile('file.bin', 'Offset',0, 'Repeat',Inf, 'Writable',false, ...
'Format',{
'double', [1 1], 'd';
'single', [1 1], 's';
'uint8' , [1 8], 'h'; % since it doesnt directly support char
'uint8' , [1 1], 'i'});
これで、通常の構造体配列としてレコードにアクセスできます。
>> rec = m.Data; % 10x1 struct array
>> rec(1) % same as: data(1,:)
ans =
d: 0.3257
s: 0.1080
h: [70 53 54 50 55 53 50 70]
i: 192
>> rec(4).d % same as: data{4,1}
ans =
0.5799
>> char(rec(10).h) % same as: data{10,3}
ans =
2B2F493F
利点は、大きなデータ ファイルの場合、マッピングの「表示ウィンドウ」をレコードの小さなサブセットに制限し、このビューをファイルに沿って移動できることです。
% read the records two at-a-time
numRec = 10; % total number of records
lenRec = 8*1 + 4*1 + 1*8 + 1*1; % length of each record in bytes
numRecPerView = 2; % how many records in a viewing window
m.Repeat = numRecPerView;
for i=1:(numRec/numRecPerView)
% move the window along the file
m.Offset = (i-1) * numRecPerView*lenRec;
% read the two records in this window:
%for j=1:numRecPerView, m.Data(j), end
m.Data(1)
m.Data(2)
end