標準ファイル入出力
ここでは、単純なファイル入出力(読み書き)を行う方法を扱います。
スポンサーリンク
標準ファイル出力
例として、「world.txt」というファイルに文字列を書き込んでみましょう:
これを実行すると、プログラムと同じ場所に「world.txt」というファイルが生成され、中に「 Hello world ! 」と記述されているはずです。
上の open 関数では、最初の引数にファイル名 "world.txt" を、次の引数にテキスト書き込みモード "w" を指定しています(定数 WRITE による指定もできます)。 モードには、他にも様々なものがあります。
open 関数は、開いたファイルに固有の識別番号「ファイルID」を割り当てて返します。 上ではそれをint 型変数 file で受け取っています。
ファイルへの書き込み/読み込み処理や、ファイルを閉じる場合には、上の例のように、 対象ファイルのファイルIDを指定します。 このように、ファイルIDで対象を識別する仕組みにより、 複数のファイルを同時に操作する事ができます。
1行ごとの書き込み
ファイル内に、行単位で内容を書いていきたい場面もよくあります。その際、C言語ユーザーの方などは、
のように、書き込み内容の末尾に「\n」を付けるというコードを書かれるかもしません。これも一応は動くのですが、改行コードの環境依存性によるややこしさが生じるため、VCSSLではあまり推奨されません。代わりに、環境に応じた改行コードで改行をしてくれる、 writeln 関数の使用が推奨されます:
標準ファイル入力
今度は、先のファイルを読み込んでみましょう:
上のopen 関数の引数 "r" はテキスト読み込みモードを意味します。 read 関数は、読み込んだファイルの内容を返します(定数 READ による指定もできます)。
read 関数の戻り値は、一般にはstring 型配列ですが、テキストモード( "r" ) モードでは要素数1 の配列を返すので、 非配列の変数 text で受け取れます。VCSSLでは、要素数 1 の配列は、非配列の変数にそのまま代入できるからです。
ただしバイナリモード( "rb" )ではバイト区切り、 TSV モード( "rtsv" )では空白・タブ区切り、CSV モード( "rcsv" ) ではカンマ区切りの配列で返されるため、配列変数で受け取る必要があります。
1行ごとの読み込み
ファイルを1 行ごとに読み込むには、以下のようにします:
このように、まず countln 関数でファイル行数をカウントし、 そして readln 関数で1 行ずつ読み込みます。先のread 関数はファイル全体を一度に読み込むためのものでしたが、 readln 関数は1 行単位で読み込むためのもので、それ以外は同じです。
標準ファイル入出力関数の仕様
上の例で用いた open 関数や readln 関数などは、標準ファイル入出力関数というもので、System ライブラリによって提供されます。
標準ファイル入出力関数の一覧
関数 | 引数 | 詳細 |
---|---|---|
open | string型のファイル名, string型のモード |
指定されたファイル名のファイルを、指定されたモードで開き、ファイルIDを割り振って返します。 モードは後の表にまとめています。"w" のように文字列リテラルで指定する他に、 WRITE のように定数を用いて指定する事もできます。 |
write | int型のファイルID, 任意型の内容1, 任意型の内容2, … |
書き込み対象ファイルに内容を書き込みます。引数を複数指定した場合、テキストモードなら連続で、TSVモードならタブ区切りで、CSV モードならカンマ区切りで、バイナリモードならバイトごとに書き込まれます。 |
writeln | int型のファイルID, 任意型の内容1, 任意型の内容2, … |
書き込み対象ファイルに内容を書き込み、改行します。引数を複数指定した場合の振る舞いは、上の write 関数と同様です。 |
read | int型のファイルID | 読み込み対象ファイルの中身を全行読み込み、string型配列として返します。テキストモードの場合は、要素数1 の配列が返され、0 番要素にファイル内容が格納されています。 その他モードの場合、TSV モードでは空白・タブ区切り、CSV モードではカンマ区切り、バイナリモードではバイト区切りで、配列にまとめて返されます。なお、TSV モードでは空白とタブを区別せず、かつ連続した空白・タブは1 つと同様に扱われます。これは数値データTSV ファイルを前提とした挙動です。より厳格なテキストTSV ファイルを扱う機能は、open.file.TextFile ライブラリが提供します。 |
readln | int型のファイルID | 読み込み対象ファイルの中身を一行だけ読み込み、string 型配列として返します。配列の内容は、上のread 関数と同様です。 |
countln | int型のファイルID | ファイル内容の行数をカウントし、int 型で返します。 |
close | int型のファイルID | ファイルを閉じます。ファイルを閉じるまでは、書き込みを保留(バッファ)されている内容があるため、閉じた時点で書き込みが全て完了します。 |
ファイル入出力モードの一覧
ファイル入出力関数の、open 関数の第二引数に指定するモードには、以下のものが存在します。
書き込みモード
書き込みモードの指定値 | モードの概要 |
---|---|
"w" または定数 WRITE | テキスト書き込みモード |
"a" または定数 APPEND | 追記テキスト書き込みモード |
"wtsv" または定数 WRITE_TSV | TSV書き込みモード |
"wcsv" または定数 WRITE_CSV | CSV書き込みモード |
"wb" または定数 WRITE_BINARY | バイナリ書き込みモード |
読み込みモード
読み込みモードの指定値 | モードの概要 |
---|---|
"r" または定数 READ | テキスト読み込みモード |
"rtsv" または定数 READ_TSV | TSV読み込みモード(※) |
"rcsv" または定数 READ_CSV | CSV読み込みモード |
"rb" または定数 定数READ_BINARY | バイナリ読み込みモード |
各モードの詳細と留意点
テキスト書き込み/読み込みモード
これらのモードは、普通のテキストファイルを扱うためのモードです。書き込み時には、引数に指定された文字列や値を、そのままテキストとしてファイル内に書き込みます。複数の引数を指定しても、区切り文字などは付かず、連続して書き込まれます。読み込み時にも、1行の内容すべてが、要素数 1 の string 配列として返されます。
バイナリ書き込み/読み込みモード
これらのモードは、バイト値を直接読み書きするためのモードです。VCSSLには1バイトぴったりの値を扱う型は無いため、読み書きは int 型の値で行います。例えば int 値の列 1, 2, 4 を書き込むと、それがそのまま符号なしバイト値 1, 2, 4 (2進数表現で 00000001, 00000010, 00000100) の列として書き込まれます。なお、1バイトに書き込み可能な値の上限は 255 (11111111) である事にご注意ください。
TSV書き込み/読み込みモード
これらのモードは、タブ・空白区切りの数値データファイルを扱うためのモードで、 CSV書き込み/読み込みモードはカンマ区切り数値データファイルのモードです。基本的に数値データを扱う事を想定したもので、単純な挙動を行います。そのため、書き込む値の中に区切り文字自身や改行が含まれていても、引用符で囲ったり、エスケープしたりなどの処理は一切されません。読み込みの際にも、そういった事を想定した処理は行われません。そのような複雑な処理を要するCSV/TSVファイルを扱う機能は、代わりに open.file.TextFile ライブラリが提供します。
y=x^2の値をCSV数値データファイルに書き出す
例として、CSV 数値データファイルを扱います。まずは書き込みです。 y=x^2 の計算結果を、ファイルに出力してみましょう:
これを実行すると、プログラムと同じ場所に、以下のような内容が書かれたファイル「x2.csv」が生成されます:
1,1
...
10,100
このような形式のファイルは、一般的なグラフソフトを用いてグラフ化する事ができます。VCSSLのグラフ描画機能でも使用できます。
y=x^2のCSV数値データファイルを読み込む
上で作ったy=x^2 の数値データファイルを、今度は読み込んでみましょう:
このプログラムを実行すると、先ほど作ったy=x^2 のデータファイルを読み込んで配列に格納し、 その内容をコマンドライン端末などに表示します。
上の readln 関数が最初に呼ばれると、ファイルの先頭行をカンマ記号「 , 」で区切って、 string 配列に格納して返ってきます。それを int 型配列のline で受け取っています。この際、暗黙の型変換により、文字列が整数へキャストされます。
line[0] は、行の中での最初の値(x値)なので、int 型配列 x に値を格納しています。同様に、行の中での次の値 line[1] は配列 y に格納しています。 これで1 行の読み込みが終わります。
readln 関数はfor 関数の中にあるので、10 回繰り返して呼ばれます。2 回目に呼ばれた際はファイルの 2 行目が呼ばれます。 このように、10 行目まで読み込み、プログラムが終了されます。
文字コードの指定
異なるオペレーションシステム上で作成したファイルをやり取りする場合などでは、 文字コードの違いによって、いわゆる文字化けが問題となる場合があります。 このような場合のために、open 関数には、引数の最後に string 型の引数を追加して文字コードを指定する事ができます。
使用できる文字コードには以下のものがあります:
文字コード | 詳細 |
---|---|
Shift_JIS | 最近まで日本語環境の主流であった文字コードですが、UTF-8に移行しつつあります。そのため、一定以上古い日本語ファイルは多くが Shift_JIS です。 |
UTF-8 | 最近のスタンダードになりつつある文字コードです。Unicode の符号化形式の一つです。 |
UTF-16 | 同様に Unicode の符号化形式の一つですが、一時期流行しかけたものの、最近はあまり使われません。 |
UTF-32 | あまり使われない Unicode 符号化形式の一つです。1文字が固定長の4バイトになるため、エンコード/デコードの処理効率が重要な一部の分野で稀に使われる事があります。 |
EUC-JP | 昔の日本語版Linux環境等でしばしば使われていた文字コードです。 |
上の文字コードは、正式な表記で記述しなければ無効となります。 例えばShift_JIS をShift-JIS と書くと向こうなのでご注意下さい。 同様にUTF-8 をUTF_8 と書いても無効となります。 大文字と小文字も区別されるため、完全に上記の通りに記述する必要があります。