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

# 9. ファイル型 (File Types)

## 9.1. ファイル構造

#### ・外部ファイルとの関連付け (標準 Pascal の場合)

標準 Pascal では **program** ヘッダのパラメータと外部ファイルとの関連付けは処理系定義となっています。つまり、規格では定められていません。

#### ・外部ファイルとの関連付け (Pascal-P5 の場合)

**Pascal-P5** では、2 つの特殊なテキストファイルが扱えます。

| 外部ファイル | 説明 |
|:---|:---|
| **prd** | 読み込み専用の外部ファイル |
| **prr** | 書き込み専用の外部ファイル |

詳しくは次の記事を参考にしてください。

 - [外部ファイルの扱い方 - 割と簡単に ’標準 Pascal' を試してみたい (Qiita)](https://qiita.com/ht_deko/items/41e95154e8da2f901698#%E5%A4%96%E9%83%A8%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E6%89%B1%E3%81%84%E6%96%B9)

#### ・外部ファイルとの関連付け (UCSD Pascal の場合)

**UCSD Pascal** などでは Reset() や Rewrite() の第 2 引数にファイル名を渡せるようにして問題を解決しています。

```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
    ...
```

#### ・外部ファイルとの関連付け (拡張 Pascal の場合)
**拡張 Pascal** では Bind() / Binding() / Unbind() とレコード型 BindingType を使って問題を解決しています。

```pascal:
procedure bindfile(var f : text);
var
  b : BindingType;
begin
  unbind(f);
  b := binding(f);
  repeat
    writeln('Enter file name:');
    readln(b.name);
    bind(f, b);
    b := binding(f);
    if not b.bound then
      writeln('File not bound--try again.');
  until b.bound;
end;
```

**See also:**

 - [UCSD Pascal を触るためだけの UCSD p-System 操作ガイド (Qiita)](https://qiita.com/ht_deko/items/50c0cb0fd3cbafc1f8e1)
 - [ISO/IEC 10206:1991 Extended Pascal (ISO)](https://www.iso.org/standard/18237.html)

## 9.2. テキストファイル

#### ・Eoln 状態の文字は？

`Eoln()` が True の状態で `Read()` によって 1 文字読み込んだ時、標準 Pascal は空白を返します。Delphi は改行コードを返します。

**See also:**

 - [7. eoln() が True の場合の文字 - Delphi と標準 Pascal の比較 (Qiita)](https://qiita.com/ht_deko/items/a13d6459227e787422ae#7-eoln-%E3%81%8C-true-%E3%81%AE%E5%A0%B4%E5%90%88%E3%81%AE%E6%96%87%E5%AD%97)

#### ・Write と Writeln

標準 Pascal でテキストファイルに出力する際、`Writeln()` ではなく `Write()` で終わった場合、不完全な行とみなされ、行末が自動で追加されます。

[(13.) テキストファイルでの Write と Writeln - Delphi と標準 Pascal の比較 (標準 Pascal コードを Delphi に移植する際の注意点) (Qiita)](https://qiita.com/ht_deko/items/a13d6459227e787422ae#13-%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%A7%E3%81%AE-write-%E3%81%A8-writeln)

### (9.2.1.) バッファ変数の代替
テキストファイルの操作に限定されますが、次の関数でバッファ変数の代替が可能です。

```pascal
  function CurrentChar(var F: Text): AnsiChar;
  begin
    Eoln(F);
    Result := (TTextRec(F).BufPtr + TTextRec(F).BufPos)^;
  end;
``` 

関数 `CurrentChar()` を使って `F^` を置き換えられます。

```pascal
var
  F: Text;
  ch: Char;
begin
  ...

  ch := F^;
  ch := CurrentChar(F);

  ...
end.
```

`CurrentChar()` 関数内の一見無意味に思える `Eoln()` は、ファイルバッファを更新する役割があります。タイミングによっては `BufPos` が `BufSize` と同じになってしまう (ポインタがファイルバッファの終端を超える) 事があるからです。

### (9.2.2.) ファイルの追記

## (9.3.) バイナリファイル

## (9.3.) 型なしファイル

#### ・型なしファイルの由来

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

この拡張は **UCSD Pascal** 由来のようです。`BlockRead()` や `BlockWrite()` も用意されていました。**Turbo Pascal** にも ver1.0 から `BlockRead()` や `BlockWrite()` があります。

:::note
テキストバッファや型なしファイルのレコードサイズのデフォルトが 128 バイトなのは、元を辿れば CP/M のセクタサイズが 128 バイトなところから来ているのだろうと思われます。
:::

**See also:**

 - [UCSD Pascal を触るためだけの UCSD p-System 操作ガイド (Qiita)](https://qiita.com/ht_deko/items/50c0cb0fd3cbafc1f8e1)

## (9.5.) 標準入出力ルーチン


# 索引
[:ramen:](https://qiita.com/ht_deko/items/986fa01c9e6cfc3fd673) [ [← 8. 集合型〔裏〕](https://qiita.com/ht_deko/items/a0044d6decd6f175365f) ] [ [↑ 目次へ](https://qiita.com/ht_deko/items/46fcdbb11cdc58872160) ] [ [→ 10. ポインタ型〔裏〕](https://qiita.com/ht_deko/items/3be4294e82653fb234c4) ]