低水準 I/O によるバイナリ データのインポート
データ インポート用の低水準関数
"低水準ファイル I/O 関数" では、ファイルの読み取りとファイルへのデータの書き込みをほぼ直接に制御できます。ただし、使いやすい "高水準関数" に比べて、これらの関数ではファイルについて詳細な情報を指定する必要があります。高水準関数とそれらでサポートされるファイル形式の一覧は、インポートとエクスポートでサポートされるファイル形式を参照してください。
高水準関数でデータをインポートできない場合は、以下のいずれかを使用してください。
fscanf
は、テキスト ファイルや ASCII ファイル、つまりテキスト エディター表示が可能なファイルに含まれる書式設定済みデータを読み取ります。詳細は、書式設定済みパターン データの読み取りを参照してください。fgetl
およびfgets
ではファイルを 1 行ずつ読み取り、各行は改行文字によって区切られます。詳細は、行単位データの読み取りを参照してください。fread
ではデータ ストリームをバイトまたはビットの単位で読み取ります。詳細は、ファイルのバイナリ データの読み取りを参照してください。
メモ
低水準ファイル I/O 関数は、ANSI® 標準 C ライブラリの関数を基に構成されています。ただし、MATLAB® にはそれらの関数の "ベクトル化" バージョンが含まれており、最小限の制御ループを使用して配列内のデータの読み取りと書き込みが行われます。
ファイルのバイナリ データの読み取り
あらゆる低水準 I/O 関数で行うように、インポートの前に fopen
でファイルを開き、ファイル識別子を取得します。ファイルの処理が終了したら、fclose
(
を使用してこれを閉じます。fileID
)
既定の設定により、fread
はファイルを 1 バイトずつ読み取り、各バイトを 8 ビット符号なし整数 (uint8
) として解釈します。fread
は列ベクトルを作成し、各要素はそれぞれファイルの各バイトに対応します。列ベクトルに含まれる値は double
クラスとなります。
たとえば、次のように作成されたファイル nine.bin
について考えます。
fid = fopen('nine.bin','w'); fwrite(fid, [1:9]); fclose(fid);
ファイル内のすべてのデータをクラス double
の 9 行 1 列の列ベクトルに読み取るには、次のようにします。
fid = fopen('nine.bin'); col9 = fread(fid); fclose(fid);
配列の次元の変更
既定の設定では、fread
によってファイル内のすべての値が列ベクトルに読み取られます。ただし、読み取る値の数を指定することや、2 次元の出力行列を作成することもできます。
たとえば、前の例で説明した nine.bin
を読み取るには次のようにします。
fid = fopen('nine.bin'); % Read only the first six values col6 = fread(fid, 6); % Return to the beginning of the file frewind(fid); % Read first four values into a 2-by-2 matrix frewind(fid); two_dim4 = fread(fid, [2, 2]); % Read into a matrix with 3 rows and % unspecified number of columns frewind(fid); two_dim9 = fread(fid, [3, inf]); % Close the file fclose(fid);
入力値の記述
ファイル内の値が 8 ビット符号なしの整数以外の場合は、値のサイズを指定します。
たとえば、次のように倍精度値で作成されたファイル fpoint.bin
について考えます。
myvals = [pi, 42, 1/3]; fid = fopen('fpoint.bin','w'); fwrite(fid, myvals, 'double'); fclose(fid);
ファイルを読み取るには次のようにします。
fid = fopen('fpoint.bin'); % read, and transpose so samevals = myvals samevals = fread(fid, 'double')'; fclose(fid);
精度の記述の一覧は、関数 fread
のリファレンス ページを参照してください。
メモリ消費量の節約
既定の設定により、fread
ではクラス double
の配列が作成されます。倍精度の値を配列に格納すると、文字、整数、または単精度の値を格納するよりも多くのメモリが必要となります。
データの格納に必要なメモリの量を減らすには、以下の方法のいずれかを使用して配列のクラスを指定します。
入力値のクラスをアスタリスク (
'*'
) を使用して一致させます。たとえば、単精度値をクラスsingle
の配列に読み取るには、次のコマンドを使用します。mydata = fread(fid,'*single')
'=>'
のシンボルによって入力値を新しいクラスにマッピングします。たとえば、uint8
の値をuint16
の配列に読み取るには、次のコマンドを使用します。mydata = fread(fid,'uint8=>uint16')
精度の記述の一覧は、関数 fread
のリファレンス ページを参照してください。
ファイルの部分的な読み取り
MATLAB の低水準関数には、ファイル内のバイナリ データの一部を読み取るためのオプションがいくつか含まれています。
配列の次元の変更で説明するように、1 回の操作で指定した数の値を読み取ります。このメソッドをファイル終端のテストと組み合わせることを検討してください。
ファイル内の特定の位置に移動してから読み取りを開始します。詳細は、ファイル内での移動を参照してください。
各要素を読み取った後に特定数のバイトまたはビットをスキップします。例については、複素数の書き込みおよび読み取りを参照してください。
ファイル終端のテスト
ファイルを開くと、ファイル内での現在の位置を示すポインターが MATLAB によって作成されます。
メモ
空のファイルを開いても、ファイルの位置指定子がファイル終端に "移動することはありません"。読み取り操作および関数 fseek
と関数 frewind
は、ファイル位置指定子を移動します。
関数 feof
を使用して、ファイル終端に達したかどうかを確認します。feof
は、ファイル ポインターがファイル終端にあるとき 1
の値を返します。それ以外の場合は 0
を返します。
たとえば、大きなファイルを次のように部分的に読み取ります。
filename = 'largedata.dat'; % hypothetical file segsize = 10000; fid = fopen(filename); while ~feof(fid) currData = fread(fid, segsize); if ~isempty(currData) disp('Current Data:'); disp(currData); end end fclose(fid);
ファイル内での移動
データの特定部分の読み取りや書き込みを行うには、ファイルの位置指定子をファイル内の任意の場所に動かします。たとえば、関数 fseek
を次の構文で呼び出します。
fseek(fid,offset,origin);
ここで以下のようになります。
fid
はfopen
から得られるファイル識別子です。offset
は、バイト単位で指定される正または負のオフセット値です。origin
によって、位置を計算する始点が指定されます。'bof'
ファイルの先頭
'cof'
ファイル内での現在の位置
'eof'
ファイル終端
または、次のようにして簡単にファイルの先頭に移動します。
frewind(fid);
特定のファイル内における現在の位置を調べるには ftell
を使用します。ftell
はファイルの先頭からのバイト数を返します。
たとえば、ファイル five.bin
を作成します。
A = 1:5; fid = fopen('five.bin','w'); fwrite(fid, A,'short'); fclose(fid);
fwrite
の呼び出しでは short
形式が指定されているため、A
の各要素では five.bin
のストレージ バイトが 2 バイト使用されます。
five.bin
を再び開いて読み取ります。
fid = fopen('five.bin','r');
ファイルの位置指定子を、ファイルの先頭から 6 バイト先に動かします。
status = fseek(fid,6,'bof');
次の要素を読み取ります。
four = fread(fid,1,'short');
読み取りの動作によって、ファイルの位置指定子は先に進みます。現在のファイル位置指定子の位置を調べるには、ftell:
を呼び出します。
position = ftell(fid) position = 8
ファイルの位置指定子を 4 バイト戻すために、fseek
を再び呼び出します。
status = fseek(fid,-4,'cof');
次の値を読み取ります。
three = fread(fid,1,'short');
他のシステムで作成されたファイルの読み取り
オペレーティング システムが異なると、バイト レベルまたはビット レベルでの情報の保管も異なっています。
"ビッグエンディアン" システムでは、メモリ内の最大のアドレスからバイトを保存します (つまり、ビッグ エンドから保存を開始します)。
"リトルエンディアン" システムでは、最小のアドレス (リトル エンド) からバイトを保存します。
Windows® システムではリトル エンディアンのバイト順を、UNIX® システムではビッグ エンディアンのバイト順を使用しています。
逆の "エンディアン" システムで作成されたファイルを読み取るには、そのファイルの作成に使用されたバイト順を指定します。バイト順は、ファイルを開く呼び出しやファイルを読み取る呼び出しで指定できます。
たとえば、リトルエンディアン システムで作成された、little.bin
という名前の倍精度値をもつファイルについて考えます。このファイルをビッグエンディアン システムで読み取るには、以下のコマンドのいずれか (または両方) を使用します。
次のコマンドでファイルを開きます。
fid = fopen('little.bin', 'r', 'l')
次のコマンドでファイルを読み取ります。
mydata = fread(fid, 'double', 'l')
ここで、'l'
はリトルエンディアンの順序を示しています。
どのバイト順がシステムで使用されているかが不明な場合は、関数 computer
を呼び出します。
[cinfo, maxsize, ordering] = computer
ordering
はリトルエンディアン システムでは 'L'
、ビッグエンディアン システムでは 'B'
となります。