Delphi
Pascal
embarcadero
objectpascal

<9> ファイル型 (標準 Pascal 範囲内での Delphi 入門)


9. ファイル型 (File Types)

標準 Pascal で言うファイルとは同じ型の要素の列からなる固定長ファイルを指します。これとは別の特殊な可変長ファイルはテキストファイルとして区別されています。

”ファイル”と聞くとストレージに保存される外部ファイルを想像すると思いますが、とりあえずその固定観念を捨てましょう。


9.1. ファイル構造

ファイル型は型の値をまとめた構造です。いわゆるランダムアクセスファイルです。

ファイル型 =

[packed] file of 基底型.

基底型は任意の型ですが、固定サイズの型に限定されます。他のファイル型やポインタ型等も使えません。

ファイル変数 F を宣言すると、その要素型を持つバッファ変数が自動的に定義されます。バッファ変数は F^ で表されます。バッファ変数はいわゆるファイルポインタです。

手続き
説明

Get()
ファイルを次の要素まで進め、
その値をバッファ変数 F^ に格納する。
要素が存在しなければ Eof()True になり
F^ は不定となる。

Put()
ファイル F にバッファ変数 F^ の値を追加する。
実行後は Eof()True になり F^ は不定となる。

Read()
ファイルからデータを読み込む

Reset()
ファイル F を先頭に位置付け、
F が空でなければ F の最初の要素が
F^ に代入され、Eof()False を返す。

Rewrite()
ファイル F を生成する。
F は空になり、Eof()True を返す。

Write()
ファイルにデータを書き込む

関数
説明

Eof()
ファイルの終わりの場合に True を返す。

次のコードは Str12 型 (長さ 12 の文字列型) のファイル型 F を使って 2 要素を書き込み後、読みだして画面に表示しています。外部ファイルはどこにも存在していません。


FileTest1.pas

program FileTest1(Output);

type
Str12 = packed array [1..12] of Char;
var
F: File of Str12;
X: Str12;
begin
Rewrite(F);
X := 'Hello,world.';
F^ := X; Put(F);
X := 'BlaisePascal';
F^ := X; Put(F);

Reset(F);
X := F^; Get(F);
Writeln(X);
X := F^; Get(F);
Writeln(X);
end.


なお、Put(), Get() 手続きは Delphi には存在しません。

F^ := X; Put(F);Write(F, X);X := F^; Get(F);Read(F, X); に置き換えることができるので、先程のコードは次のように書く事もできます。


FileTest2.pas

program FileTest2(Output);

type
Str12 = packed array [1..12] of Char;
var
F: File of Str12;
X: Str12;
begin
Rewrite(F);
X := 'Hello,world.';
Write(F, X);
X := 'BlaisePascal';
Write(F, X);

Reset(F);
Read(F, X);
Writeln(X);
Read(F, X);
Writeln(X);
end.


Read()Write() は任意の個数の実パラメータが渡せる特殊な手続きです。例えば Write(F, X1, X2, X3) とすれば、ファイルに要素を 3 回追記できます。

さて、このファイル型ですが、外部ファイルと関連付けて使うにはどうすればいいのでしょうか?

標準 Pascal では次のようにして外部ファイルを扱う事ができます。


FileTest3.pas

program FileTest3(Output, DATAFILE);

type
Str12 = packed array [1..12] of Char;
var
DATAFILE: File of Str12;
X: Str12;
begin
Rewrite(DATAFILE);
X := 'Hello,world.';
Write(DATAFILE, X);
X := 'BlaisePascal';
Write(DATAFILE, X);

Reset(DATAFILE);
Read(DATAFILE, X);
Writeln(X);
Read(DATAFILE, X);
Writeln(X);
end.


変数定義部にある DATAFILE 変数が program ヘッダのパラメータにも書かれていますよね?こうする事によって、標準 Pascal は外部ファイルにアクセスします。"変数名 = Program ヘッダのパラメータ名 = 外部ファイル名"です。上記例だと DATAFILE という名前のファイルができる事になります。

image.png

ここまで標準 Pascal の検証には PASCAL-P5 を使ってきたのですが、残念ながらこの外部ファイルには対応していないようで、実際に機能を試す事はできませんでした。

image.png

何故外部ファイルがこんな扱いになっているのかと言うと、クラシック Pascal は外部ファイルの扱い方も環境依存と考えていたからです。しかしながら、この仕様だとパラメータ名や変数名にドット . が使えないため、拡張子のあるファイル名は使えず、別のディレクトリにあるファイルも扱うことができません。

この問題を解決する UCSD Pascal の拡張は Reset() や Rewrite() にファイル名を渡せるというものでした。


RANDOMACCESS.pas

PROGRAM RANDOMACCESS;

VAR
DISK: FILE OF
RECORD
NAME: STRING[20];
DAY, MONTH, YEAR: INTEGER
END;
BEGIN
RESET(DISK, 'RECORDS.DATA');
WHILE NOT EOF(INPUT) DO
BEGIN
...

Delphi だと必ずファイル変数と外部ファイルを関連付けて扱う必要があり、そのための AssignFile() という手続きが用意されています。

手続き
説明

AssignFile()
外部ファイルの名前をファイル変数と関連付ける。
Turbo Pascal では Assign()。

ANSI 版 Delphi だと標準 Pascal との違いは AssignFile() の記述だけです。


FileTest4.pas

program FileTest4(output);

{$APPTYPE CONSOLE}
type
Str12 = packed array [1..12] of Char;
var
F: File of Str12;
X: Str12;
begin
AssignFile(F, 'DATA.FILE');

Rewrite(F);
X := 'Hello,world.';
Write(F, X);
X := 'BlaisePascal';
Write(F, X);

Reset(F);
Read(F, X);
Writeln(X);
Read(F, X);
Writeln(X);
end.


Unicode 版 Delphi だとちょっと変更が必要です。


FileTest4.pas

program FileTest4(output);

{$APPTYPE CONSOLE}
type
Str12 = packed array [1..12] of AnsiChar;
var
F: File of Str12;
X: Str12;
begin
AssignFile(F, 'DATA.FILE');

Rewrite(F);
X := 'Hello,world.';
Write(F, X);
X := 'BlaisePascal';
Write(F, X);

Reset(F);
Read(F, X);
Writeln(AnsiString(X));
Read(F, X);
Writeln(AnsiString(X));
end.


See also:


9.2. テキストファイル

テキストファイルは文字の列からなる可変長の行のファイルです。いわゆるシーケンシャルアクセスファイルです。テキストファイル型を宣言するには定義済みの型 Text を使います。

テキストファイル型 =

[packed] file of Text.

テキストファイル型は基底型 Char のファイル型に (仮想の) 改行を加えて拡張したものによって定義されます。テキストファイル型は "(packed) file of Char" と同義ではありません。改行は次のテキストファイル型用手続き / 関数を使って生成したり検出したりできます。

手続き
説明

Readln(F)
テキストファイル F を次の行の先頭まで読み飛ばす。
F^ には次の行の最初の文字が入る。

Writeln(F)
テキストファイル F に改行を追加する。

関数
説明

Eoln(F)
テキストファイル F が改行位置の時に True を返す。

テキストファイル型は基底型 Char のファイル型を拡張したものですから、文字の読み書きには Read(F, Ch)Write(F, Ch) を使います。Ch は Char 型の変数です。

プログラムヘッダに記述することのできる InputOutput は標準入力と標準出力に割り当てられた宣言済みのテキストファイル型変数です。

See also:


(9.3.) 型なしファイル

Delphi には型なしファイル型というものがあります 1。いわゆるバイナリファイルを扱うファイル型です。

型なしファイル型 =

[packed] file.

手続き
説明

BlockRead(F)
ファイルから 1 つ以上のレコードを読み取って
変数に格納する。

BlockWrite(F)
1 つ以上のレコードを変数から
開いているファイルに書き込む。

Read() と Write() の代わりに BlockRead() および BlockWrite() という 2 つの手続きを使用すると、高速のデータ転送を行うことができます。

”型なし" なので、複数の任意の型を使ってファイルを読み書きする事ができます。

See also:


索引

[ ← 8. 集合型 ] [ ↑ 目次へ ] [ → 10. ポインタ型 ]





  1. この拡張は UCSD Pascal 由来のようです。BlockRead() や BlockWrite() も用意されていました。