標準ファイル入出力
ここでは、単純なファイル入出力を扱うためのシステム関数を扱います。
スポンサーリンク
標準ファイル入出力
例として、「world.txt」というファイルに文字列を書き込んでみましょう:
このプログラムを実行すると「world.txt」というファイルが生成され、中に「 Hello world ! 」と記述されているはずです。
上の open 関数では、最初の引数にファイル名 "world.txt" を、次の引数にテキスト書き込みモード "w" を指定しています。 モードには、他にも様々なものがあります。 open 関数は、開いたファイルに固有の識別番号「ファイル番号」を割り当てて返します。 上ではそれをint 型変数 file で受け取っています。
ファイルへの書き込み/読み込み処理や、ファイルを閉じる場合には、上の例のように、 対象ファイルのファイル番号を指定します。 このように、ファイル番号で対象を識別する仕組みにより、 複数のファイルを同時に操作する事ができます。
標準ファイル入力
今度は、先のファイルを読み込んでみましょう:
上のopen 関数の引数 "r" はテキスト読み込みモードを意味します。 read 関数は、読み込んだファイルの内容を返します。 read 関数の戻り値は、一般にはstring 型配列ですが、テキストモード( "r" ) モードでは要素数1 の配列を返すので、 非配列の変数 text で受け取れます。
ただしバイナリモード( "rb" )ではバイト区切り、 TSV モード( "rtsv" )では空白・タブ区切り、CSV モード( "rcsv" ) ではカンマ区切りの配列で返されるため、配列変数で受け取る必要があります。
1行ごとの読み込み
ファイルを1 行ごとに読み込むには、以下のようにします:
このように、まずcountln 関数でファイル行数をカウントし、 そしてreadln 関数で1 行ずつ読み込みます。先のread 関数はファイル全体を一度に読み込むためのものでしたが、 readln 関数は1 行単位で読み込むためのもので、それ以外は同じです。
標準ファイル入出力関数の種類
システム関数に用意されている標準ファイル入出力関数には、以下のものが存在します:
関数 | 引数 | 詳細 |
---|---|---|
open | string ファイル名, string モード |
指定されたファイル名のファイルを、指定されたモードで開き、ファイル番号を割り振って返します。 モードには、以下のようなものがあります。"w" のように文字列リテラルで指定する他に、 WRITE のようにシステム定数を用いて指定する事もできます。 - 書き込みモード -
- 読み込みモード -
テキストモードは、普通のテキストファイルを扱うためのモードです。バイナリモードは、バイト値ごとにダイレクトに入出力を行うためのモードです。 TSV モードは、タブ・空白区切りの数値データファイルを扱うためのモードで、 CSV モードはカンマ区切り数値データファイルのモードです。基本的に数値データを扱う事を想定したもので、単純な挙動を行います。 複雑な処理を要するテキストCSV/TSV ファイルを扱う機能は、代わりにopen.file.TextFile ライブラリが提供します。 |
write | int ファイル番号, string 内容1, string 内容2, … |
書き込み対象ファイルに内容を書き込みます。引数を複数指定した場合、テキストモードなら連続で、TSVモードならタブ区切りで、CSV モードならカンマ区切りで、バイナリモードならバイトごとに書き込まれます。 |
writeln | int ファイル番号, string 内容1, string 内容2, … |
書き込み対象ファイルに内容を書き込み、改行します。引数を複数指定した場合の振る舞いは、上のwrite関数と同様です。 |
read | int ファイル番号 |
読み込み対象ファイルの中身を全行読み込み、string型配列として返します。 テキストモードの場合は、要素数1 の配列が返され、0 番要素にファイル内容が格納されています。 その他モードの場合、TSV モードでは空白・タブ区切り、CSV モードではカンマ区切り、バイナリモードではバイト区切りで、配列にまとめて返されます。
なお、TSV モードでは空白とタブを区別せず、かつ連続した空白・タブは1 つと同様に扱われます。これは数値データTSV ファイルを前提とした挙動です。より厳格なテキストTSV ファイルを扱う機能は、open.file.TextFile ライブラリが提供します。 |
readln | int ファイル番号 | 読み込み対象ファイルの中身を一行だけ読み込み、string 型配列として返します。配列の内容は、上のread 関数と同様です。 |
countln | int ファイル番号 | ファイル内容の行数をカウントし、int 型で返します。 |
close | int ファイル番号 | ファイルを閉じます(この時点で書き込み完了)。 |
y=x^2の値をCSV数値データファイルに書き出す
例として、CSV 数値データファイルを扱います。まずは書き込みです。 y=x^2 の計算結果を、ファイルに出力してみましょう:
これを実行して「x2.txt」を開くと、以下のような内容となっています:
1,1
…
10,100
このような形式のファイルは、一般的なグラフソフトを用いてグラフ化する事ができます。
y=x^2のCSV数値データファイルを読み込む
上で作ったy=x^2 の数値データファイルを、今度は読み込んでみましょう:
このプログラムを実行すると、先ほど作ったy=x^2 のデータファイルを読み込んで配列に格納し、 その内容をコマンドライン端末などに表示します。
上のreadln 関数が最初に呼ばれると、ファイルの先頭行をカンマ記号「 , 」で区切って、 string配列に格納して返ってきます。それをint 型配列のline で受け取っています (この際、暗黙の型変換により、文字列が整数へキャストされます)。
行の1 列目のline[0]はx の値なので、int 型配列x に値を格納し、同様にline[1]をy に格納しています。 これで1 行の読み込みが終わります。 readln 関数はfor 関数の中にあるので、10 回繰り返して呼ばれます。2 回目に呼ばれた際はファイルの2 行目が呼ばれます。 このように、10 行目まで読み込み、プログラムが終了されます。
文字コードの指定
異なるオペレーションシステム上で作成したファイルをやり取りする場合などでは、 文字コードの違いによって、いわゆる文字化けが問題となる場合があります。 このような場合のために、open 関数には、引数の最後にstring 型の引数を追加して文字コードを指定する事ができます。
使用できる文字コードには以下のものがあります:
文字コード | 引数への記述 | 詳細 |
---|---|---|
シフトJIS | Shift_JIS | シフトJISでファイルにアクセスします。ShiftとJISの区切りはアンダーバー「_」である事にご注意ください。 |
EUC-JP | EUC-JP | EUC-JPでファイルにアクセスします。EUCとJPの区切りはハイフン「-」である事にご注意ください。 |
Unicode | UTF-8 UTF-16 UTF-32 |
Unicode でファイルにアクセスします。引数へは「Unicode」ではなく、「UTF-8」など、エンコーディングの実装を指定します。 |
上の文字コードは、正式な表記で記述しなければ無効となります。 例えばShift_JIS をShift-JIS と書くと向こうなのでご注意下さい。 同様にUTF-8 をUTF_8 と書いても無効となります。 大文字と小文字も区別されるため、完全に上記の通りに記述する必要があります。