ファイル操作 





 
 
エラー処理
 
 

 Mindでは統一したエラー処理の機構を持っている。本章のファイル操作では多くの場面でエラー処理が行われるので、常にエラー発生を意識してプログラムを作成する必要がある。なお、エラー処理はファイル操作に限らず、ソケット操作でも関わっている。
 エラー発生を意識すべき大きな理由は、あるファイル操作でエラーが発生したとき、それを無視して、あるいはうっかりしてプログラムを先に進めると、また別の(より深刻な)エラーが発生するなど事象が複雑になり、問題の解決が難しくなるからである。

 エラー発生の例としてファイルのオープンを挙げる。例えば存在しないファイルをオープンしようとするとエラーとなる。「オープン」の仕様を眺めてみよう。

スタック仕様

<物理ファイル名>で <論理ファイル>を オープン → ・

プログラム例

"file1.txt"で ファイル1を オープンする

 スタック仕様で分かるように、「オープン」は、成功したかどうかの情報をスタックに返さない。別途、処理単語「エラー?」によって調べる方法をとっているからである。
 したがって、エラー検出・対策を含めたプログラムは下記のような記述となる(「オープン」に関しては、ほとんどがこのスタイルになるだろう)。
    "file1.txt"で ファイル1を オープンし     エラー?         ならば <エラー処理する>         つぎに
  Mindのライブラリ内部には、このようなエラー処理を支援するいくつかの単語が定義されている。これらについて以下に解説する。


構文=
エラー? → <真/偽>
 エラー処理を行うような処理単語の実行によってでエラーが発生したかかを調べる機能である。


構文=
エラー文字列  (文字列実体変数)
  Mindのライブラリ内部に確保されている文字列実体変数である。前記した「エラー?」が真を返したとき、この変数を参照することで、そのエラーに対応する標準的なエラーメッセージを得ることができる。例えば、「オープン」時のエラーの一つとして次のようなメッセージが登録される。
ファイルが有りません。
 「エラー?」により、エラーが有ったかどうかが判定でき、次にそのエラーが有った場合、どのようなエラーだったかを変数「エラー文字列」を参照することで知ることができる‥という手順である。たとえば以下のような記述が典型的なものになる。
    エラー?         ならば 「エラー:」を 表示し エラー文字列を 一行表示し             終り         つぎに     ・・・・・・
 プログラムによっては次のように簡単にすることもある。
    エラー?         ならば 終り         つぎに     ・・・・・・
 上記はエラー文字列を使っていないが、もし、この処理単語を呼び出している上位側で「エラー?」による検出と、「エラー文字列」の参照をおこなうのであれば、結果的に同じ処理をすることになる。


構文=
<文字列>を エラー登録 → ・
 ユーザー自身が、エラー発生するような処理単語を定義する場合、指定するメッセージをエラー文字列として登録できる。これによって、その処理単語を利用する側が「エラー?」を実行したときに真が返されるようになる。
 次に示す「エラークリア」と共に、「オープン」のような、エラー処理をサポートするような処理単語をユーザー側で作る場合に使用される。

構文=
エラークリア → ・
 エラー状態をクリアする。内部的には、文字列実体変数「エラー文字列」をクリアしているだけである。自身がエラー処理をサポートする処理単語を作る場合に使用する。そのような処理単語の実行の始めに「エラークリア」を実行して欲しい。
 (プログラム例)
○○とは     エラークリアし     ・・・・・・・・し     △△が失敗?         ならば 「△△が失敗しました。」を エラー登録し             終り      ←失敗したときはこのように脱出         つぎに     ・・・・・・・・し     ・・・・・・・・し


 
 
重大エラーについて
 
 

  Mindでいう「重大エラー」というのは、文字通り、重大な(致命的な)エラーであり、プログラムがこれ以上処理を続行できないと(Mindシステムが、あるいはユーザプログラムが)判断した場合を指す。プログラムは強制的に終了させられる。
 処理単語としての「重大エラー」は、言ってみれば「重大エラーにする」というニュアンスの処理単語であり、そのようなエラーをわざと引き起こす。Mind標準ライブラリが内部で使っているが、ユーザーも使うことができる。
 「重大エラー」を実行すると、次のようなことが行われる。
 なお、この単語の実行内部でプログラムの終了が行われることから、本単語から戻った場合の処理はまったく考慮する必要はない(そもそも、戻ってこない)。
 例えば、
メインとは     "file1.txt"で ファイル1を オープンし     エラー?         ならば エラー文字列で 重大エラーにする             (ここには来ない)         つぎに     ・・次の処理をする・・
 ごく簡単なプログラムでは上記のようなエラー処理も良いだろう。「重大エラー」を呼び出した後に戻って来ることはないため、「・・ ならば 重大エラー さもなければ ・・ つぎに」のように2分岐にする必要はなく、単に「つぎに」で合流してしまって構わない。
 前記のプログラムの発展形として次の例を示す。「エラー? ならば ・・で 重大エラー」という記述があちこちに現れるようであれば、それだけをおこなう下位の処理単語を定義してしまえば、全体としてよりシンプルになる‥という考えである(下記では下位定義に局所処理単語を使った)。
メインとは   エラー処理とは (・ → ・)     エラー?         ならば エラー文字列で 重大エラーにする         つぎに   本体とは     "file1.txt"で ファイル1を オープンし     エラー処理し     ・・・・・し     エラー処理し     ファイル1を クローズし     エラー処理し     ・・・・・すること。


 
 
物理ファイル名と論理ファイル名
 
 

  Mindでは物理ファイル名と論理ファイル名という2種類のファイル名を扱う。
 物理ファイル名とは、ディスク上の(=OSが管理する)実際のファイル名のことであり、たとえば、
memo.txt
のようなものである。
 これに対し、論理ファイル名はもっと抽象的な名前であり、たとえば、
メモ帳
のように日本語で、しかも長い名前を自由に付けることができる。
 重要なのは、「ドライブ名」とか「ディレクトリ名」などで指定するファイルの存在場所とか、OSにおけるファイル名の命名規則などは、論理ファイルではまったく関知しない点である。
 例えば、ファイルへ書き込みを行う際、最初に物理ファイル名と論理ファイル名の対応をとっておきさえすれば、その後は、
○○を メモ帳に 書き込む
と記述すればよく、その売り上げ帳が実際にはどのようなドライブやディレクトリに格納されるのかをプログラマが考えないで済む仕掛けになっている。


 
 
論理ファイルの宣言
 
 

 ファイル(論理ファイル)は次のように宣言(定義)してから使用する。

構文=
<論理ファイル>は ファイル。 <論理ファイル>は ファイル 長さ <バッファ長さ>。
 上段はバッファ長さを省略した形式で、簡単に済ませるならこれで良い。この場合はバッファ長さは1024バイトである。
 下段はバッファ長さを明示するもので、最低でも128バイトが必要であるが、特別な用途で0を指定することもできる。この長さは(0以外の場合は)効率の点から、128、256、512、1024、・・(あとは1024の倍数)などを薦める。
 本処理単語も含め、以降の解説で、スタック仕様(構文)を示した中に、
<論理ファイル>
とあった場合、この位置に論理ファイル名(今回の例では メモ帳)を記述する必要がある。
 先のメモ帳を例にとれば、次のような宣言となる。
メモ帳は ファイル。 メモ帳は ファイル 長さ 8192バイト。
 また、論理ファイル名を引用する場合であるが、すべて実記が必要であり、スタック渡しできない。例えば、「オープン」では、
<物理ファイル名>で <論理ファイル>を オープン → ・
という使い方をするのだが、上記で物理ファイル名はスタック渡しできるが、論理ファイル名は必ず記述しなければならない(「オープン」では送り仮名「を」も強制される)。(注1)
注1
「オープン」のように、〔データ〕と〔論理ファイル名〕のペアを指定する処理単語では、この2つを逆順に記述することもできる。詳細は第6章(数値演算)の中の〔データと変数の逆転介入〕の項を参照。


 
 
ファイルのオープンとクローズ
 
 

 ファイルはアクセスする前に必ず「オープン」し、アクセスが終わった段階で「クローズ」する必要がある。
 ファイルのオープンには次の2種類がある。

構文=
(書き込み用) <物理ファイル名>で <論理ファイル>を 新規オープンする → ・ (読み出し用) <物理ファイル名>で <論理ファイル>を オープンする → ・         注:論理ファイル名の送り仮名「を」は必須         注:「オープン」から戻ったら必ずエラー検査をおこなうこと
 「新規オープン」は新しいファイルを生成するもので、書き込みのために用いられる。既存ファイルが存在するときは、一旦サイズがゼロにリセットされ、これからの書き込みに備えることになる。
 「オープン」は既存のファイルをオープンする場合であり、主に読み出しのために用いられる(特別な指示をすればこのオープンでも書き込みが可能)。
 物理ファイル名は、文字列定数として表記することのほか、スタック渡しでも良い。例えば次のような方法が考えられる。

   [1]    
(ファイル名は定数として)     "memo.txt"で メモ帳を オープンする

   [2]    
(コマンドラインから起動引数で)     起動引数(1)で メモ帳を オープンする

   [3]    
(キーボードから入力)     「メモ帳のファイル名を入力してください:」を 表示し     文字列入力したもので メモ帳を オープンする
 上記いずれの場合も、物理ファイル名が登場するのはこの場面(オープン時)だけであり、いったんオープンしてしまえば、そういった違いはもはやプログラム上に現れず、「メモ帳」という抽象的な名前(論理ファイル名)を指示してアクセスすることになる。
 「オープン」、「新規オープン」は、エラー処理が行われている。ユーザーは後続して、「エラー?」により、エラー有無を確認すること。詳しくは エラー処理のセクション を参照されたい。

 ファイルのクローズは次のように簡単である。

構文=
<論理ファイル>を クローズする → ・        注:論理ファイル名の送り仮名「を」は必須        注:書き込み系処理ではクローズから戻ったらエラー検査をおこなうこと
 ファイルをオープンしたら、必ずクローズを行う必要がある。
 プログラム中で、ファイルのオープンに失敗したら、そもそもオープンされていなのだからクローズの必要も無い。しかし一旦オープンが成功した後は、たとえその先で各種エラーが発生して処理を打ち切るような場合であっても、必ずクローズだけはおこなって欲しい。
 「クローズ」を呼び出した際のエラー発生について補足する。
 読み出し系の処理だけをおこなった後のクローズでは、あえてエラー検査をしなくても構わない。
 しかし書き込み動作が有った後のクローズでは、必ずエラー処理をおこなって欲しい。
 多くの場合、書き込みデータはバッファリングされるため、最後にバッファに残ったデータの書き込みがクローズのタイミングで行われることが多く、結果として、本来は書き込み系処理単語の呼び出しでエラーとなるべきものが(たとえば、ディスク・フルなど)、クローズ時にエラー発生となることもある。それを正しく検出するためにも、書き込み系ではクローズ後のエラーを必ず見るようにしたい。


 
 
ファイルの読み出し
 
 


 
一行読み出し
 
 ファイルからの読み出しは、読み出す単位によって色々な方法があるが、1行単位の「一行読み出し」が最もよく使用される。 (注:「一文字読み出し」と「読み出し」は特殊な用途)。
文字列操作では「一文字xx」の処理単語がよく使われるが、ファイルでは「一行読み出し」、「一行書き込み」が使われることが多い。

構文=
<論理ファイル>から 一行読み出し → <文字列>                  論理ファイル名の送り仮名は必須で、「から」のほか、「より」、「を」も可
 論理ファイルから1行分の文字列を読み出す。次のようになっている。

構文=
データ終り? → <真/偽>
 ファイルからの読み出しで必ず使う処理単語である。
 最後のデータを読み出したあと、なおもデータを読み出した場合に真が返される。真が返された場合には、直前の読み出しは無効なので、データを使用してはならない。
 ファイルを読み出すプログラムでは、必ずこの「データ終り?」を用いて読み出しの繰り返し処理を打ち切る必要がある。


 
一行読み出しのサンプル
 
 まず、読み出しに使うテキストファイルであるが、次のような、ごく短いファイルがあったとする。
    (ファイル "memo.txt")
あいう ab
 このファイルの全行を読み出して単に表示するプログラムの例とその実行結果を示す。
    (プログラム "readline.src")
メモ帳は ファイル。 メインとは         行は  文字列     "memo.txt"で メモ帳を オープンし     エラー?         ならば エラー文字列で 重大エラーにし         つぎに     ここから         メモ帳から 一行読み出し 行に 入れ         データ終り?             ならば 打ち切り  ←このパスでは読み出しデータは使わない             つぎに         「行=[」を 表示し 行を 表示し 「]」を 一行表示し     繰り返し     メモ帳を クローズする。
 (実行結果)
>readline 行=[あいう] 行=[ab] >
注2
 「一行読み出し」で読み出された文字列に行末コード(CRあるいはLF)は含まれないので、その行データを1行分表示するような場合には、明に改行する必要がある。
 また、行末コードそのものについて言うと、一般的に、Windows環境では CR+LF の2文字が使われ、UNIX系OSでは(EUCで入出力する設定になっていれば)LFの1文字が使われることが多く、OSによる違いがある。しかしMindでの「一行読み出し」では、行末コードがどちらであっても正しく行が把握されるので、どちらのOSによって生成されたテキストファイルなのかを意識せずに済む。(しかし漢字を含むテキストでは、文字コード体系の違いはあるので別途対処の必要あり)


 
一文字読み出し
 
 ここまでテキストファイルから1行単位で読み出す機能について解説をしたが、利用頻度は低いものの、1文字単位での読み出しをおこなう「一文字読み出し」を解説する。

構文=
<論理ファイル>から 一文字読み出し → <文字>            論理ファイル名の送り仮名は必須で、「から」のほか、「より」、「を」も可
 「一文字読み出し」は指定する論理ファイルから次の1文字を読み出すもので、次のような仕組みになっている。
 少し前に解説したサンプルファイル memo.txt を再度取り上げる。このファイルを文字単位で詳細に見ると以下のようになっているはずである。
ファイル "memo.txt"
 あ い う [CR]  [LF]  a b [CR]  [LF] 

 論理ファイル名を「メモ帳1」とすれば、読み出しは次のように記述することになる。
○○とは         文字1は 変数     〜     ここから         メモ帳から 一文字読み出し 文字1に 入れ         データ終り?             ならば 打ち切り             つぎに         文字1を ・・・し     繰り返し     〜
 上記のプログラムによって読み出される文字群は以下の通りで、当然ながら先のテキストファイルの内容そのものである(1度の読み出し単位が1論理文字であることが重要)。
 あ い う  [CR]  [LF]  a  b  [CR]  [LF] 


 
逆方向に一行読み出し
 

構文=
<論理ファイル>から 逆方向に一行読み出し → <文字列>              論理ファイル名の送り仮名は必須で、「から」のほか、「より」、「を」も可
 この機能は他のプログラム言語にはない、Mindだけの特徴である。
 「逆方向に一行読み出し」は「一行読み出し」とそっくりの処理単語である。 ただし、末尾行から始めて先頭行に向かって読むのが特徴である。逆方向‥とは言っても、行の内部(左右位置)まで逆になるわけではない。
 なお、オープン直後ではこの単語を実行しても何も読み出されない(最初から データ終り? が真を返す)ので注意したい。なぜなら、ファイルの読み出しポインタ(内部的なポインタ)はオープン直後にはファイル先頭を指しており、その位置は、本単語にとっては終点位置だからである。
 そのため、「オープン」のあとで、「ファイルポインタを末尾に設定」(後述)を必ず実行する。そうすることで、読み出しポインタがファイル末尾に設定され、末尾から先頭に向かっての読み出しが可能になる。
 「一行読み出し」と「逆方向に一行読み出し」は混在して使用することもできる(行ったり来たりできる)。どちらかの操作によって、ファイルが終点まで到達し、「データ終り?」が真を返すようになった場合においても、その逆の読み出しを行うことで、再び読めるようになる。
 テキストファイルの末尾のn行を表示するプログラムの例とその実行結果を示す。
 (UNIX系コマンドの tail に相当するが、Windowsには標準でこのようなコマンドが無いので役に立つ)
    (プログラム "mtail.src")
対象ファイルは ファイル。 メインとは         オプションは 文字列         ファイル名は 文字列         引数位置は  変数         行数は    変数         合否は    変数         行は     文字列     ※−−−−−−−−−−−−−−−−−−−−−−−−−−−※     ※ Usage: mtail [-N] file (-Nを省略すると10行を表示) ※     ※−−−−−−−−−−−−−−−−−−−−−−−−−−−※   (起動引数を解析)     起動引数(1)を オプションに 入れ     オプションの 左端文字が '-'に 等しい         ならば           (行数を得る)             オプションを 一文字削除し             オプションを 数値変換し 行数と 合否に 入れ             合否が 偽?                 ならば 「行数が誤りです」で 重大エラー                 つぎに           (ファイル名は引数2に)             2番を 引数位置に 入れ         さもなければ             10行を 行数に 入れ  ※←デフォルトの行数           (ファイル名は引数1に)             1番を 引数位置に 入れ         つぎに     起動引数(引数位置)を ファイル名に 入れ   (オープンと末尾移動)     ファイル名で 対象ファイルを オープンし     エラー?         ならば エラー文字列で 重大エラーにし         つぎに     対象ファイルを ファイルポインタを末尾に設定し     エラー?         ならば 対象ファイルを クローズし             エラー文字列で 重大エラーにし         つぎに   (N行だけ逆方向に読み出し)     行数を     回数指定し         対象ファイルから 逆方向に一行読み出し 捨て         データ終り?             ならば 打ち切り             つぎに     繰り返し   (正方向に読み出し)     ここから         対象ファイルから 一行読み出し 行に 入れ         データ終り?             ならば 打ち切り             つぎに         行を 一行表示し     繰り返し     対象ファイルを クローズする。
 (実行結果)
>type 20lines.txt ←まずファイル全体の内容を確認 1行目 2行目 3行目 4行目 5行目 6行目 7行目 8行目 9行目 10行目 11行目 12行目 13行目 14行目 15行目 16行目 17行目 18行目 19行目 20行目 >mtail -5 20lines.txt ←mtailプログラムの実行 16行目 17行目 18行目 19行目 20行目 >


 
その他の読み出し
 
 今まで解説した処理単語のほかに、以下の機能もある。いずれも上級編で解説する。。

 
 
ファイルへの書き込み
 
 
 書き込みに関しても、読み出しと同様に幾種類もの方法があるが、よく使用されるものを以下に解説する。
 書き込み系の単語はいずれもエラー発生を伴う。1例としては、ディスクが一杯というものがある。エラーが発生すると、それ以後のすべての書き込みは無視されるようになる。また、そのファイルのクローズは必ずエラー状態で終わる(たとえ、クローズそのものは成功であったとしても)。「クローズを呼び出した際のエラー発生」の解説も合わせて参照されたい。


構文=
<文字>を  <論理ファイル>に 一文字書き込み → ・ <文字列>を <論理ファイル>に 書き込み    → ・        <論理ファイル>に 改行を書き込み → ・ <文字列>を <論理ファイル>に 一行書き込み  → ・        注:論理ファイル名の送り仮名は必須。「に」のほかに「へ」も可        注:本単語から戻ったらエラー検査をおこなうこと
 「一文字書き込み」は、指定する文字(コード)を指定するファイルに書き込む。漢字も1度の呼び出しで処理できる。
 データ内容には言語は介入しないので、バイナリデータやNull文字(00H)を含むどのようなコードも書き込むことができる。
 1文字の書き込み毎にエラー検査するのはコーディングの負担が(CPUの負担も)大きいので、もう少し大きな単位でエラー検査しても構わないだろう。
 「書き込み」は、指定する文字列(文字列情報で渡す)を指定するファイルに書き込む。行末コードつかないので、これを繰り返すことで複数の文字列を結果的に長い1行として書き込むこともできる。
 漢字の介入は無いため(ありのまま書き込むので)バイナリのメモリブロックを書き込んでも構わない。
 「改行を書き込み」は、指定するファイルに行末コードとしてCR(0DH)、LF(0AH)の2文字を(Linux版MindではLFの1文字を)書き込む。
 「一行書き込み」は、指定する文字列(文字列情報で渡す)を指定するファイルに書き込み、さらに行末コードとしてCR(0DH)、LF(0AH)の2文字を(Linux版MindではLFの1文字を)書き込む。


 
 
ファイルへの追加書き込み
 
 
 既に存在するファイルの末尾にさらに追加して書き込みを行う(アペンド)場合、あるいは末尾でなくても、ファイルの途中のある部分を書き換える方法を本項で示す。
 複数の処理単語を使って以下のような手順により実現する。
  1. アペンドモード」を実行する (次の「オープン」を書き込みモードでおこなうための通知)
  2. オープン」によってオープンする
  3. ファイルポインタの設定機能、(アペンドであれば「ファイルポインタを末尾に設定」)を実行し、書き込みポインタを所定の位置(たとえばファイル末尾)に移動する
  4. xx書き込み」系の単語を使ってデータを書き込む
  5. クローズ」する
 上記 1 と 3 で示した新しい機能について以下に解説する。


 
アペンドモード
 

構文=
アペンドモードにする → ・
 「アペンドモード」を実行すると、これに続いて行う「オープン」が書き込みモードでおこなわれ、その論理ファイルに対して書き込みができるようになる。(本来、「オープン」は読み出しモードなのだが、特別に書き込みモードになる)

 
ファイルポインタの設定
 

構文=
      <論理ファイル>の ファイルポインタを先頭に設定 → ・ <位置>を <論理ファイル>に ファイルポインタを設定    → ・       <論理ファイル>の ファイルポインタを末尾に設定 → ・ <位置>を <論理ファイル>に ファイルポインタを末尾からの位置に設定 → ・ <移動量>だけ <論理ファイル>を ファイルポインタを移動 → ・        注:本単語から戻ったらエラー検査をおこなうこと
 この処理単語群は、ファイルポインタ(次にファイルをアクセスする位置)を指定た箇所に移動するものである。なお、ファイルをオープンした直後のファイルポインタは0(ファイル先頭)である。
 「ファイルポインタを先頭に設定」 はファイルポインタを位置0(先頭)に移動する。
 「ファイルポインタを設定」 は指定した位置にポインタを設定する。位置の単位はバイトで、ファイル先頭からの相対位置である。
 「ファイルポインタを末尾に設定」 は文字通りであるが、「末尾」とは正確にいうなら、「末尾文字の次の位置」である。もちろんそこが、次に追加データを書き込むべき位置になる。
 「ファイルポインタを末尾からの位置に設定」 は、末尾から測った距離(末尾からのバイト単位の相対位置)を設定する。なお、ファイルの成長方向を正の方向とするため、普通は負の値になる。たとえば、ファイルの最後の1バイトの箇所に設定するには、−1 を指定する。
 「ファイルポインタを移動」 は、現在の位置から指定量だけファイルポインタを移動させる。ファイルの成長方向を正の方向とするため、戻るには負の値を指定する。なお、何らかの読み出し処理や書き込み処理が行わた後、バッファにテキスト残があるような場合であっても、バッファのフラッシュとテキスト残量の補正が行われ、正しい移動量が計算される。
すべてのファイルポインタの設定語について言えることだが、これらの単語を実行すると、内部のバッファは自動的にフラッシュ(吐き出し)されるようになっているので、バッファを経由する読み出し(一文字読み出し、一行読み出し)あるいは書き込み(一文字書き込み、一行書き込みなど)をおこなっている途中で別の位置にポインタを設定しても構わない。つまり、バッファ残のせいで処理がおかしくなることは無い。

 
ファイルポインタの参照
 

構文=
<論理ファイル>の ファイルポインタ → <位置>        注:本単語から戻ったらエラー検査をおこなうこと
 現在のファイルポインタの値を得るものである。


 
 
ファイルからファイルへの代入
 
 

構文=
<論理ファイル>を <論理ファイル>に 入れる → ・   ↑複写元       ↑複写先        注:論理ファイル名の送り仮名は必須。          複写元は「を」「から」「より」が使える。複写先は「に」「へ」が使える        注:本単語から戻ったらエラー検査をおこなうこと
 ファイルに対して「入れる」を作用させると、ファイルの内容のすべてが複写される。
 複写元、複写先の論理ファイルは、あらかじめオープンしておくこと。
 1文字あるいは1行単位で複写する方法に比べると格段に高速であり、単なる複写でいい場合にはこの方法を使うことを勧める。(Windowsのcopyコマンド、Linuxのcpコマンドとほぼ同じ速度で複写する)
 なお、論理ファイルのバッファ長さ(○○は ファイル 長さ △△。 ‥‥ の△△)にかかわらず、本処理単語内部で独自のバッファを動的に確保する。そのため、もし論理ファイルへの処理がこの複写だけなのであれば、バッファ長さは0で構わない。


構文=
<物理ファイル名>を <物理ファイル名>に ファイル複写 → ・   ↑複写元       ↑複写先        注:物理ファイル名の送り仮名は必須。          複写元は「を」「から」「より」が使える。複写先は「に」「へ」が使える        注:本単語から戻ったらエラー検査をおこなうこと
 物理ファイル名を指定した複写機能であり、実行速度も含め、OSのcopyコマンドにきわめて近い働きをする。
 先の「入れる」に比べると本単語では、物理ファイル名を指定する点、オープン/クローズがこの中で行なわれる点、そしてタイムスタンプが複写される点が異なる。
 なお、複写元にワイルドカードを指定したり、複写先をディレクトリとするのは誤りなので注意すること。(OSのcopyコマンドでは許されるので、うっかり記述しがちである)。
(誤り) "file1.txt"を "dir1"に ファイル複写する   ←複写先にディレクトリを指定している "file*.txt"を 〜〜〜〜           ←複写元にワイルドカードを指定している (正しい) "file1.txt"を "dir1¥file1.txt"に ファイル複写する
 複写時にタイムスタンプも含めて複写するが、「ファイル複写」の前に次の処理単語を実行しておくことでタイムスタンプの複写を抑制することができる(このモードは「ファイル複写」の中で自動リセットされる)。

構文=
タイムスタンプ複写抑止 → ・


 
 
論理ファイルを指定するその他の機能
 
 

構文=
<論理ファイル>を 再オープン → ・        注:論理ファイル名の送り仮名「を」は必須。        注:本単語から戻ったらエラー検査をおこなうこと
 一度オープンし、何らしらの処理をおこない、最後にクローズをかけたファイルがあって、同じ物理ファイル名と論理ファイル名で再度オープンする場合、普通に「オープン」を使ってももちろん良いのだが、「再オープン」を使うと、物理ファイル名を省略できるので容易になる。 書き込みを行なった後の、ベリファイ用のオープンなどに利用すると良い。
 ちなみに、ファイルを最後まで読んだあと、クローズ、オープンして再び頭から読み直したい場合には、本機能ではなく、「ファイルポインタを先頭に設定」を使うほうがスマートである。


構文=
<論理ファイル>の 物理ファイル名 → <物理ファイル名>        注:論理ファイル名の送り仮名「の」は必須。        注:本単語から戻ったらエラー検査をおこなうこと
 オープン中、あるいは、そのあとクローズされている論理ファイルについて、そのオープン時の物理ファイル名を知ることができる。


構文=
<論理ファイル>の 読み出しバイト数 → <行番号>        注:本単語から戻ったらエラー検査をおこなうこと
 直近の 「一行読み出し」、「逆方向に一行読み出し」、「読み出し」 をおこなったあとで本単語を実行することで、ファイルから今読み出したデータのサイズ(バイト数)を知ることができる。
 行単位のアクセスである「一行読み出し」「逆方向に一行読み出し」では、読み出した文字列には行末コードは含まれないが、本単語が返すバイト数は行末コードを含んだものである。
 たとえば、Windows環境の通常のテキストであれば、ほとんどの場合、「一行読み出し」で得られた文字列のバイト数よりも、本単語で得られるバイト数が2バイトだけ大きいはずである(行末にあるCR+LFの分)。


構文=
<論理ファイル>の 読み出し行番号 → <行番号>        注:本単語から戻ったらエラー検査をおこなうこと
 直近の「一行読み出し」あるいは「逆方向に一行読み出し」をおこなったあとで本単語を実行することで、今読み出した行の行番号を知ることができる。

論理ファイルを指定するものとしては、このほかに上級編にて「タイムスタンプを読み出し」などファイル属性のアクセス機能を解説している。


 
 
物理ファイル名を指示するその他の機能
 
 

構文=
<物理ファイル名>が ファイル有り? → <真/偽> <物理ファイル名>を ファイルを削除 → ・ <物理ファイル名1>を <物理ファイル名2>に ファイル名変更 → ・   注:「ファイルを削除」と「ファイル名変更」は、戻ったらエラー検査すること
 「ファイル有り?」は、指定するファイルが存在するかどうかを検査する。ファイルが存在しない場合は偽を返すが、これはエラー扱いではない。
 「ファイル削除」は、Windowsのeraseコマンド、Linuxのrmコマンドと類似の機能である。ただし、ワイルドカードは指示できない。
 「ファイル名変更」は、Windowsのrenameコマンド、Linuxのmvコマンドと類似の機能である。ドライブ名あるいはパス名は旧名の方だけにつける。ファイル名だけでなく、ディレクトリ名も変更することができる。


 
 
パス名を指示するその他の機能
 
 

構文=
<パス名>が ディレクトリ有り?   → <真/偽> <パス名>を ディレクトリを削除   → ・ <パス名>を ディレクトリを作成   → ・  注:パス名には相対パスも使える  注:「ディレクトリを削除」と「ディレクトリを作成」は戻ったらエラー検査すること  注:ディレクトリ名の変更は「ファイル名変更」にておこなう
 上記単語群はディレクトリを操作する機能である。


 
 
カレントディレクトリの参照と設定
 
 

構文=
カレントディレクトリ → <カレントディレクトリ(文字列)>
 文字通り、カレントディレクトリをフルパスの文字列として得る機能である。
 ちなみに、カレントディレクトリの親ディレクトリを得るには、
カレントディレクトリの パス名を得て ・・・
 とすると良い。さらにその親であれば、
カレントディレクトリの パス名を得て パス名を得て ・・・
 となる。


構文=
<ディレクトリ>を カレントディレクトリ設定 → ・   注:(Windows) ドライブ名は省くこともできる。逆にドライブ名だけも可   注:(Windows) ネットワークパス(UNC)も指定できる   注:本単語の呼び出しから戻ったらエラー検査をおこなうこと
 指定するディレクトリ(フルパス)をカレントディレクトリとして設定する。
 相対ディレクトリを指定することもできる(例: .. を指定して親ディレクトリに移る )。
 この機能により変更したカレントディレクトリは、そのプログラムが走行している間のみに有効なものであり、プログラムが終了すれば本設定にかかわらず、元のカレントディレクトリに戻る。逆に言えば、プログラムでカレントディレクトリを変更したあと、終了時に明にカレントディレクトリを戻す必要は無い。

(Windows環境のみ)
    (プログラム "setcurdir.src")
メインとは     起動引数(1)を カレントディレクトリ設定し     エラー?         ならば エラー文字列で 重大エラー         つぎに     「変更後のカレントディレクトリは 」を 表示し     カレントディレクトリを 表示し 「 です。」を 一行表示する。
 (実行結果)
C:¥pmind¥sample>setcurdir obj 変更後のカレントディレクトリは C:¥pmind¥sample¥obj です C:¥pmind¥sample>setcurdir ¥¥machine¥dir1 変更後のカレントディレクトリは ¥¥machine¥dir1 です C:¥pmind¥sample>


 
 
ファイルまたはディレクトリの検索
 
 
この機能は 上級編 にて「タイムスタンプを読み出し」などファイル属性のアクセス機能と共に解説する。


 
 
ファイル名の解析・分解
 
 
 ファイル名を解析・分解する豊富な機能が用意されている。
 まず以降の解説のために、Mindで使っている用語の定義をしておく。
名称 値 (Windows) 値 (Linux)
ファイル名 C:\topdir\subdir\test.src /topdir/subdir/test.src
パス名 C:\topdir\subdir /topdir/subdir
ドライブ名 C (Windowsのみの概念)
主ファイル名 C:\topdir\subdir\test /topdir/subdir/test
純ファイル名 test.src test.src
拡張子 src src
Mindでいう「パス名」は一般的なコンピュータの用語定義と若干異なるので注意したい。Mindのパス名は純ファイル名を含まず、そのファイルを収容しているフォルダへのパスとなる。
 以下にファイル名の解析・分解をおこなう単語群を解説する。



構文=
<ファイル名>を パス名と純ファイル名に分離 → <パス名> <純ファイル名> <ファイル名>の パス名を得る        → <パス名> <ファイル名>の 純ファイル名を得る     → <純ファイル名>    注:ファイル名に上位ディレクトリを含まない場合はパス名部は空列となる
 上のグループは、ファイル名を与えられ、それを パス名純ファイル名 に分離する、あるいはそれらを個別に得る単語群である。
(例)         パス名は 文字列         純名は  文字列   〜略〜   "C:¥topdir¥subdir¥test.src"を パス名と純ファイル名に分離し                          パス名と 純名に 入れ                           ↓    └→test.src                        C:¥topdir¥subdir
(例)   "C:¥topdir¥subdir¥test.src"の パス名を得て パス名に 入れ                            ↓                          C:¥topdir¥subdir   "C:¥topdir¥subdir¥test.src"の パス名を得て パス名を得て パス名に 入れ                                   ↓                                 C:¥topdir
(例)   "C:¥topdir¥subdir¥test.src"の 純ファイル名を得て 純名に 入れ                               ↓                              test.src




構文=
<ファイル名>を 主ファイル名と拡張子に分離 → <主ファイル名> <拡張子> <ファイル名>の 主ファイル名を得る     → <主ファイル名> <ファイル名>の 拡張子を得る        → <拡張子>    注:ファイル名に拡張子が含まれない場合は拡張子部は空列となる    注:ディレクトリ部にピリオドが含まれていても、それを拡張子とはみなさない
 上のグループは、ファイル名を与えられ、主ファイル名拡張子 に分離する、あるいはそれらを個別に得る単語群である。
(例)         主ファイル名は 文字列         拡張子は    文字列   〜略〜   "C:¥topdir¥subdir¥test.src"を 主ファイル名と拡張子に分離し                          主ファイル名と 拡張子に 入れ                           ↓       └→src                        C:¥topdir¥subdir¥test
(例)   "C:¥topdir¥subdir¥test.src"の 主ファイル名を得て 主ファイル名に 入れ                                ↓                            C:¥topdir¥subdir¥test
(例)   "C:¥topdir¥subdir¥test.src"の 拡張子を得て 拡張子に 入れ                             ↓                            src




構文=
<ファイル名>に パス指定有り?  → <真/偽> <ファイル名>に 拡張子指定有り? → <真/偽> <ファイル名>が 有効ファイル名? → <真/偽> <パス名>が   有効パス名?   → <真/偽>
 上のグループは、ファイル名を検査する単語群である。
 「パス指定有り?」は、ファイル名にパス(ディレクトリ)を含むかを検査する単語である。Windows環境なら ¥ が、Linux環境なら / が含まれているかを調べる。
 「拡張子指定有り?」は、ファイル名の純ファイル名部(パスを除いた部分)に . を含むかを検査する単語である。(パス部に . が含まれていても拡張子とはみさなさい)
 「有効ファイル名?」は、ファイル名が文法的に正しいかどうかを検査する。
 「有効パス名?」は、パス名(ディレクトリ名)が文法的に正しいかどうかを検査する。
「有効ファイル名?」と「有効パス名?」は良く似ている。ファイル名やパス名に使える文字が共通だからである。違いの一例としては、たとえば ... は有効なファイル名ではないが、有効なパス名である‥といったものがある。
また、たとえば、Windows環境で D:¥ 、Linux環境で / は有効なファイル名ではないが、有効なパス名である。




構文=
パス記号 → <'¥' または '/'>  (文字コード)
 WindowsとLinuxで共通のソースプログラムにしたい場合、ファイル名の操作は注意を要する部分の1つである。上記の「パス記号」はMindのライブラリ内部で数値定義されたシンボルであり、Windowsなら'¥'が、Linuxなら'/'の1文字が返される(文字列ではなく文字なので注意)。
 たとえば、ディレクトリ名と純ファイル名を合成してディレクトリ含みのファイル名を作りたい場合、以下のようなプログラムにしておけば、同じソースでWindowsとLinuxとで共有できる。
フルパスファイル名は 文字列実体 長さ ファイル名長さ。 フルパスファイル名を作成とは (・ → フルパスファイル名)         ディレクトリは 文字列         ファイル名は  文字列     ・・・・     ディレクトリを フルパスファイル名に 入れ     パス記号を   フルパスファイル名に 一文字追加し     ファイル名を  フルパスファイル名に 追加し     フルパスファイル名を 返すこと。


 
 
外部プログラムの実行
 
 
 Mindのプログラム内から外部のプログラムを実行することができる。

構文=
<文字列(プログラム名と引数)>を プログラム実行 → <真/偽>
 ちょうど、コマンド プロンプトの中でキー入力したコマンドを実行するときのようにプログラムを実行できる。
 戻値として偽(0)が返されるのは、指定したプログラムが見つからないか、あるいはその他のエラーの場合である。その場合は「エラー文字列」や「エラー表示」を使用することでエラー判定と処理をおこなうことができる。
 以下は例である。
ファイル一覧コマンドは 文字列定数 "dir /w"。 ファイル一覧を表示するとは (・ → ・) ファイル一覧コマンドを プログラム実行し 偽?         ならば 「エラー:」を 表示し エラー表示し         つぎに。
 上の例のように、「プログラム実行」に渡す文字列は、その先頭にプログラム名を書き、もし引数も必要なら空白に続いて引数を書く。
 内部的にはシェルを介在してプログラムを起動するため、ファイルとして存在するプログラムのほか、シェルの内部コマンド(上記のdirコマンドがそれ)も実行できる。
 もしプログラム名やそこへのパスに空白を含む場合はダブルクオートで囲む必要がある。しかしダブルクオート囲みの中にダブルクオートが入ると面倒なので、文字列全体は「 」で囲むと良い。
 プログラム名は、もしPATH環境変数に含まれるパスに存在するプログラムであればパスの明示は不要だが(つまりPATH検索が行われる)、そうでない場合はパスを明示する。この点も、コマンド プロンプト内でキーボードからプログラムを起動するのと同じである。


構文=
子プロセスの終了パラメータは 変数。   (標準ライブラリ内の大域変数)
 標準ライブラリ内に定義された大域変数である。
 「プログラム実行」(上級編における「子プロセスを実行」、「子プロセスを起動」も含む)が成功して子プロセスから戻った時、その子プロセスの終了パラメータ(終了コード)をこの変数を見ることで参照できる。
 Windowsのバッチファイルで if errorlevel%errorlevel% などとするもの、あるいは Linuxのシェルスクリプトで $? で参照する終了コードと同じ意味である。一般的に呼び出した先のプログラムでエラーが発生して戻ってきたときに非ゼロの値が設定されるとされている。


構文=
終了パラメータは 変数。         (標準ライブラリ内の大域変数)
 先の「子プロセスの終了パラメータ」と似ていてまぎらわしいが、先のは自分が呼び出し親であり子プロセスでの実行結果を知りたい場合に使うものだったが、本変数は、自身のプログラムが親から呼び出される場合に、自身から親に終了コードを戻したい場合に使う。立場が逆になったものである。
 プログラムでこの大域変数に値を入れてから「メイン」を終了する、あるいは「実行終り」で積極的にプログラム終了する際、この変数の値がOSに通知される。何もしなければこの値は0となっている。
 なお、Mindのプログラムの走行中に重大エラーが発生して強制終了する場合、変数「終了パラメータ」には1が設定されるようになっている(呼び出し親にエラー発生を知らせるため)。
 以下は終了パラメータに値を設定する例である。
メインとは     ・・・・・     ・・・が ・・・?         ならば 「エラーが有りました」を 一行表示し             1を 終了パラメータに 入れ             実行終り         つぎに     ・・・・・