Main Content

マッピングされたファイルの読み取り

この例では、異なるメモリ マップを 2 つ作成してから、適切な構文を使用して各マップから読み取る方法を説明します。次に、マップのプロパティの変更方法と、データを解析する方法を説明します。

MATLAB® ワークスペースからの変数の読み取りに使用する MATLAB コマンドと同じコマンドを使用して、メモリにマッピングしたファイルの内容を読み取ることができます。メモリ マップの Data プロパティにアクセスすることによって、マッピングされたファイルの内容は現在アクティブなワークスペースにある配列として表示されます。ファイル内のデータを指定して読み取るには、配列内のデータをインデックスで指定します。パフォーマンスを上げるには Data フィールドを変数にコピーし、この変数を使用してマッピングしたファイルを読み取ります。

dataRef = m.Data;

for k = 1 : N

y(k) = dataRef(k);

end

一方、memmapfile オブジェクトから直接読み取ると遅くなります。

for k = 1 : N

y(k) = m.Data(k);

end

数値配列のメモリ マップからの読み取り

まず、倍精度浮動小数点数の 5000 行 1 列の行列を含むサンプル データ ファイル records.dat を作成します。

rng('default')
randData = rand([5000,1]);

fileID = fopen('records.dat','w');
fwrite(fileID,randData,'double'); 
fclose(fileID);

100 個の倍精度浮動小数点数をファイルからメモリにマッピングし、マッピングしたデータの一部を読み取ります。メモリ マップ m を作成します。Offset 値を 1024 に指定し、ファイルの先頭から 1024 バイトの位置よりマッピングを開始します。Repeat 値を 100 に指定して、100 個の値をマッピングします。

m = memmapfile('records.dat','Format','double', ...
      'Offset',1024,'Repeat',100);

Data プロパティを変数 d にコピーします。次に、d の形式を表示します。

d = m.Data;

whos d
  Name        Size            Bytes  Class     Attributes

  d         100x1               800  double              

マッピングしたデータは 800 バイトの配列になります。これは、8 バイトを必要とする double 値が 100 個あるからです。

ベクトル d のインデックスを指定して、選択した数値のセットをファイルから読み取ります。

d(15:20)
ans = 6×1

    0.3510
    0.5132
    0.4018
    0.0760
    0.2399
    0.1233

非スカラー構造体のメモリ マップからの読み取り

ファイル records.dat のデータの一部を、複数のデータ型からなるシーケンスとしてマッピングします。

関数 memmapfile を呼び出して、メモリ マップ m を作成します。

  m = memmapfile('records.dat',  ...
      'Format', {              ...
         'uint16' [5 8] 'x';   ...
         'double' [4 5] 'y' });

Format パラメーターは、ファイルの最初の 80 バイトを uint16 値の 5 行 8 列の行列として、その後の 160 バイトを double 値の 4 行 5 列の行列として扱うように memmapfile に指示します。このパターンはファイル終端まで繰り返されます。

Data プロパティを変数 d にコピーします。

d = m.Data
d=166×1 struct array with fields:
    x
    y

d は 166 個の要素からなる構造体配列で、フィールドが 2 つあります。ファイルが複数のデータ型の繰り返しシーケンスとしてマッピングされているので、d は非スカラー構造体配列です。

配列内の構造体を 1 つ調べ、各フィールドの形式を表示します。

d(3)
ans = struct with fields:
    x: [5x8 uint16]
    y: [4x5 double]

ファイルからその構造体の x フィールドを読み取ります。

d(3).x
ans = 5x8 uint16 matrix

   62645   30353   12492   16358   58958    9377   48754   16323
   14152   21370   16352   21042   61010   33482   16321   22042
    2657   16336   37389   35249   45699   16353   47136   59002
   16360   41668    9638   33351   16366    3344   58286   31491
    5368   55234   24278   16364   55768    7216    7184   16336

MATLAB は、Format プロパティの指定どおりにデータ ブロックの形式を uint16 値をもつ 5 行 8 列の行列に設定します。

ファイルからその構造体の y フィールドを読み取ります。

d(3).y
ans = 4×5

    0.8407    0.9293    0.6160    0.5853    0.7572
    0.2543    0.3500    0.4733    0.5497    0.7537
    0.8143    0.1966    0.3517    0.9172    0.3804
    0.2435    0.2511    0.8308    0.2858    0.5678

MATLAB は、データ ブロックの形式を double 値をもつ 4 行 5 列の行列に設定します。

マップのプロパティの変更とデータの解析

この例の部分では、メモリ マップ経由でファイルから読み取ったデータのフーリエ変換をプロットする方法を説明します。続いて、既存マップのプロパティをいくつか変更し、データ ファイルの別の部分から読み取りを行って、そのデータを基にヒストグラムをプロットします。

サンプル ファイル double.dat を作成します。

randData = rand([5000,1]);
fileID = fopen('double.dat','w');
fwrite(fileID,randData,'double'); 
fclose(fileID);

1025 バイト目から始まる double 型の 1,000 個の要素の memmapfile object を作成します。

m = memmapfile('double.dat','Offset',1024,  ...
      'Format','double','Repeat',1000);

Data プロパティを変数 k にコピーします。次に、マップと関連付けられているデータを取得し、マップに含まれる最初の 100 個の値の FFT (高速フーリエ変換) をプロットします。

k = m.Data;
plot(abs(fft(k(1:100))))

このときにはじめてデータが参照され、実際にファイルから MATLAB のアドレス空間にマッピングされます。

マップのプロパティを変更しますが、同じファイルを引き続き使用します。メモリ マップのプロパティ値を変更するたびに、MATLAB はファイルをメモリにマッピングし直します。

m.Offset = 4096;
m.Format = 'single';
m.Repeat = 800;

現在、msingle 型の 800 個の要素の memmapfile オブジェクトです。このマップは、ファイル records.dat の 4096 バイト目から始まります。

ファイルの 4096 バイト目から始まる部分を読み取り、そのデータの最大値を計算します。このコマンドは新しい領域をマッピングし、前の領域のマッピングを解除します。

X = max(m.Data)
X = single
    3.2278e+38

参考

関連するトピック