ファイル入出力

openメソッド

これまでのプログラムでは、データの入力を行なうときは gets を利用した。これは、Rubyプログラム起動時に引数を何も 指定しないと端末(キーボード)から、引数にファイルを指定した場合は そのファイルから1行ずつ内容を読む。

./score.rb
   (gets は端末からデータを読み込む)
./score.rb score.txt
   (gets は socre.txt ファイルからデータを読み込む)

そのいっぽう、プログラムに与えるデータが決まり切っている 場合などは特定のファイルにそれを保存しておいて、 そのファイルからデータを読むことができる。 そのために利用するのがopenメソッドである。

ファイルからの読み込み処理

ファイルからの読み込みには、上記openメソッドに、読み込み たいファイル名と、読み込むためのモード指定 "r" を指定する。 変数は、そのファイルへのアクセスのときに使う任意のものにする。

open("hoge.txt", "r") do |f|
  while line = f.gets        # f.gets で hoge.txt を1行読み line に入れる
    …処理…
  end
end

とすると、カレントディレクトリにある hoge.txt というファ イルを読み込み専用モードで開き、開いた結果を変数 f に入れる。 このファイルから1行ずつデータに読むには、f に備わっている gets メソッドを使う。つまり、f.gets とすること で、開いたファイルから1行ずつ読んだ結果が返ってくる。

ファイルへの書き出し

ファイルへの書き出しは、open メソッドに、 書き込むためのモード指定 "w" または、"a" いず れかを(用途に応じて)指定する。たとえば、以下のような処理となる。

open("result.txt", "w") do |output|
  …処理…
  output.print "……書き出す文字列……"
  …処理…
end

書き出しを行なう場合には、openしたときの変数に 備わっている書き出し用メソッドを使う。今までのプログラムで、端末にメッセー ジを出力するときに利用していた、print, printf, puts メソッド がそのまま使える。

たとえば、

x = 5*5
printf("結果は %d です\n", x)

とすると、標準出力に

結果は 25 です

と出力されるが、

x = 5*5
open("gogo.out", "w") do |gogo|
  gogo.printf("結果は %d です\n", x)
end

とすると、カレントディレクトリの gogo.out というファイル に

結果は 25 です

と出力される。また、オープンモードを "a" にした場合、 つまり

x = 5*5
open("gogo.out", "a") do |gogo|
  gogo.printf("結果は %d です\n", x)
end

とすると、gogo.out ファイルの末尾に追加される。

標準入出力

printf などの出力メソッドでとくに出力先を指定しない場合は標準出力となる。 標準出力は STDOUT に結び付けられている。標準出力は Ruby プログラムの起動時に変えられていることもある。たとえば、

./program.rb > output.txt

とした場合は output.txt ファイルが標準出力となる。 このように標準出力をファイルにすり替えることをリダイレクション という。

Ruby プログラムを起動した端末画面は標準エラー出力で、これは STDERR に結び付けられている。したがって、

STDERR.puts("異常データです")

とした場合は、たとえ標準出力がリダイレクションされていたとしても、 出力先は端末画面となる。

また、標準入力は STDIN に結び付けられている。 Rubyプログラムを起動するときに

./program.rb input.txt

とした場合、gets メソッドは input.txt からデータを読むため、標準入力から読めない。明示的に STDIN を指定し STDIN.gets とすることで読み取ることができる。

外部コマンドとの入出力

open メソッドでは、ファイルだけでなく、

ことができる。この場合ファイル名の代わりに、| (パイプ)記 号とコマンドを結合したものを指定すればよい。たとえば、

open("| ls -l", "r") do |filelist|
  while line = filelist.gets
    …処理…
  end
end

とすると、ls -l コマンドを実行した結果を1行ずつ読み込む ことができる。また、

open("| bc -l", "w") do |calc|
  calc.puts "9/2"
end

とすると、bc -l コマンドを起動し、それに対して

9/2\n

を送出する(putsは末尾に改行文字を追加出力する)。


本日の目次