【Ruby】ファイル操作をするクラスとメソッド
Fileクラス
ファイルに関するクラスです。
ファイルの作成、削除、閉じる、読み込みや書き込み、属性の変更など様々なメソッドがあります。
ファイルのモード
Fileクラスのメソッドの第2引数には、ファイルのモードを指定できます。
ファイルに書き込したり、追記する場合に指定します。何も指定しなければ、読み取りモードになります。
オプション | 説明 |
---|---|
r | 読み込み |
w | 書き込み。既存ファイルの場合は、ファイルの中身を空にする |
a | 追記。ファイルの末尾に追記される |
r+ | 読み書き。ファイルの先頭から読み書きを行う。 |
w+ | 読み書き。既存ファイルの場合は、ファイルの中身を空にする |
a+ | 読み書き。ファイルの末尾から読み書きを行う。 |
ファイルを開く
メソッドは、「open」です。
ファイルモードは全てのオプションを指定できます。
構文
File.open("ファイル名", "ファイルモード")
(例) sample.txtを開きます。
File.open('sample.txt')
ファイルを読み込む
メソッドは、「read」です。
構文
インスタンス変数名.read(length)
readの引数lengthには、読み込むサイズを整数で指定します。
sample.txt
(例) sample.txtの内容を読み込みます
file = File.open('sample.txt')
puts file.read
Hello World
Hello Ruby
Hello Java
(例) Hello Worldだけ読み込む場合は、readの引数に11を指定する
file = File.open('sample.txt')
puts file.read(11)
Hello World
ファイルを閉じる
メソッドは、「close」です。
基本的にファイルは開く・閉じるはセットです。
構文
インスタンス変数名.close
(例) sample.txtを開いて、閉じます。
file = File.open('sample.txt')
=> #<File:sample.txt>
file.close
=> nil
閉じ忘れ防止のために、ブロック形式にすると終了時に自動的にファイルが閉じます。
基本はブロック形式で記述しましょう。
File.open('sample.txt') { |file| puts file.read }
ファイルの作成
メソッドは、「new」と「open」です。(一般的には「open」を使うことが多いです。)
メソッドの第一引数には「ファイル名」を第2引数には、ファイルモードを指定します。
ファイルモードは、「w」か「w+」、「a」か「a+」を指定します。
構文
File.open("ファイル名", "ファイルモード")
(例) sample.txtを書き込みモードで作成します。
file = File.open('sample.txt', "w")
実行すると、sample.txt
が作成されました。
ファイルに書き込む
メソッドは、「write」です。(putsでも可能)
ファイルモードは、「r+」、「w」か「w+」、「a」か「a+」を指定します。
構文
インスタンス変数名.write("書き込むもの")
(例) sample.txtの中に書き込みます
file = File.open('sample.txt', "w")
file.write("Hello Ruby")
ブロックで処理することもできます。
File.open('sample.txt', "w") do |io|
io.write("Hello Ruby")
end
(例) sample.txtというファイルに「Hello Ruby」が書き込まれる
ファイルを削除する
メソッドは、「delete」です。
構文
File.delete("ファイル名")
(例) sample.txtを削除します。
File.delete('sample.txt')
=> 1
IOクラス
Fileクラスのスーパークラスで、基本的な入出力機能を備えたクラスです。
read,write,closeなど多くのメソッドは前述で紹介したFileクラスでも使用できます。
sample.txt
の内容を例にそれぞれのメソッドについて説明します。
Hello World
Hello Ruby
Hello Java
ファイルの読み込み
foreach / each_line / each
引数で指定したファイルを開いて、各行をブロックに渡して実行します。
# foreach
IO.foreach("sample.txt") {|i| puts i}
# each_line
io = open("sample.txt")
io.each_line("sample.txt") {|i| puts i}
# each
io = open("sample.txt")
io.each("sample.txt") {|i| puts i}
Hello World
Hello Ruby
Hello Java
readlines
ファイルを全て読み込んで、各行を配列として返します。
File.open("sample.txt").readlines
=> ["Hello World\n", "Hello Ruby\n", "Hello Java"]
gets / readline
ファイルから一行読み込んで、読み込みに成功した時にはその文字列を返します。
getsとreadlineの違いは、EOFに到達した時です。getsはnil,readlineはEOFErrorを返します。
io = open("sample.txt")
=> #<File:sample.txt>
io.gets
=> "Hello World\n"
> io.gets
=> "Hello Ruby\n"
> io.gets
=> "Hello Java"
io.gets
=> nil
eof?
ファイルの終端まで達したかどうかを調べるメソッドです
先程のファイルでio.getsでnilになったので、終端になっています。
eof?メソッドで終端に達したかどうかを確認できます。
io = open("sample.txt")
io.gets
=> #<File:sample.txt>
=> "Hello World\n"
> io.gets
=> "Hello Ruby\n"
> io.gets
=> "Hello Java"
io.gets
=> nil
io.eof?
=> true
ファイルのポインタの移動や設定
開いたファイルの読み書きをする場所、ファイルのポインタの移動や設定をするメソッドがあります。
rewind
ファイルポインタを先頭に移動して、行番号(lineno)を0にします。
io = open("sample.txt")
=> #<File:sample.txt>
io.readline
=> "Hello World\n"
# 0になります
io.rewind
=> 0
# 行番号(lineno)が0になります
io.lineno
=> 0
io.readline
=> "Hello World\n"
pos
ファイルポインタの位置を取得したり、指定できます。
io = open("sample.txt")
=> #<File:sample.txt>
io.readline
=> "Hello World\n"
# "Hello World\n"は、12番目です。
io.pos
=> 12
# ファイルポインタを18に指定します。
io.pos = 18
# 18番目から読み込みます。
io.read
=> 18
=> "Ruby\nHello Java"
seek
ファイルポインタを指定した数だけ第2引数の位置から移動します。
位置への移動が成功すれば0を返します。
<第2引数>
IO::SEEK_SET:ファイルの先頭から (デフォルト)
IO::SEEK_CUR:現在のファイルポインタから
IO::SEEK_END:ファイルの末尾から
io = open("sample.txt")
=> #<File:sample.txt>
# ファイルポインタを5番目に移動
io.seek(5)
=> 0
# 6番目から読み込み
io.read
=> " World\nHello Ruby\nHello Java"
# ファイルの先頭からポインタを10番目に移動
io.seek(10, IO::SEEK_SET)
=> 0
# 11番目から読み込み
io.read
=> "d\nHello Ruby\nHello Java"
例題
Ruby技術者認定試験合格教本にある模試問題です。
①無限ループ処理
File.open("sample.txt") do |io|
# while not(=until)→指定した条件が満たされるまで ループを実行します。
# ファイルが終端に達する(trueになる)までループする
while not io.eof?
# readの引数は、読み込むサイズを整数で指定するので、1は「H」になる
print io.read(1)
# ファイルの先頭から読み込む
io.seek(0, IO::SEEK_SET)
end
end
「H」が無限ループする
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
HHHHHHHHHHHHHHHHHH.............
②ファイルの文字を逆順に書き込む処理
123456789
open("sample.txt", "r+") do |f|
data = f.read
data.reverse!
f.rewind
f.write(data)
end
逆順に書き込まれる
987654321
コードの解説
open("sample.txt", "r+") do |f|
# ファイルを読み込む
data = f.read
=> "123456789"
# 逆順にします
data.reverse!
=> "987654321"
# ファイルポインタを0にします
f.rewind
=> 0
# 出力できたバイト数(今回は9文字)を返します。
f.write(data)
=> 9
end
Discussion