ファイルを書き込みするプログラムを作るには、ファイルポインタを理解しなければなりません。Rubyでもファイルポインタを使います。なお、RubyのファイルポインタとはFileオブジェクトであり、ファイルにデータを書き込みする処理を作るには、Fileオブジェクトのメソッドを使います。
今回はRubyのFileオブジェクトを利用したファイル書き込み処理の作り方を紹介します。
Rubyでファイルに書き込みするには
Rubyのプログラムでファイルにデータを書き込みする処理を作るなら、どのようなコードを思い浮かべるでしょうか。Rubyにはファイルに書き込みする処理を記述する方法が幾つもあります。その中から最適な方法を選べるようになりましょう。
とはいえファイルに書き込み機能の基本はどれも同じです。まずはRubyのプログラムでファイルに書き込みする機能の基本について解説します。
ファイルポインターという考え方
今使われている多くのプログラミング言語は、C言語の影響を受けています。Rubyも例外ではありません。具体的にRubyのファイル操作に関する考え方は、C言語のやり方に似ています。そしてC言語でファイルを扱うポイントとは、ファイルポインターを使う点です。
ファイルポインターとは、ファイルのデータの場所を示すアドレスでアクセスするための特別な変数です。ファイルを開くとファイルポインターが作られ、最初はファイルの先頭データを指すアドレスが格納されています。
それをファイルの最終アドレスまで動かしながらデータを読み込みしたり、書き込みすることでファイルを読んだり書いたりすることが可能です。
C言語でファイルを開く例
#include <stdio.h> int main() { FILE *fp = fopen("sample.txt", "w"); fprintf( fp, "ファイルに書き込みしました。"); fclose(fp); }
上の例は、fpがファイルポインタです。なおC言語では*が付く変数をポインターとして扱います。
ファイル書き込みの基本
先ほど紹介したファイルポインターを使うことで、先頭アドレスから最終アドレスまでファイルポインターを動かすループを作り、その中でファイルポインターにデータを書き出すようにすれば、ファイルを書き出すプログラムを作れます。
ただしファイルを開く際、どのように開くかで書き込み方法が変わります。例えば、新規ファイルを開くと先頭アドレスに何も無い状態から書き込みます。一方、既存のファイルを開いた時点で最終アドレスに移動して書き込みすれば、そのファイルに追記するモードで書き込みすることが可能です。
さらにファイルポインターを動かしてから書き込みすれば、そのファイルの途中から新しいデータを上書きして保存する、といった処理も作れます。
FILEクラスを活用する
これまでファイルポインターの使い方を説明してきましたが、Rubyのプログラムでファイルポインタと同じ機能を実現するのがFileオブジェクトです。Rubyでファイルに書き込みする処理を作るには、FILEクラスを使ってFileオブジェクトを作りましょう。
次からFileオブジェクトの作り方と、Fileオブジェクトに定義されたメソッドの使い方を紹介します。
Rubyで書き出す処理の基本
先ほど紹介したようにRubyでファイルを書き出す処理ではFILEクラスを使い、ファイルポインタに相当するFileオブジェクトを使います。そして、Fileオブジェクトのメソッドを利用してファイルにデータを書き込みます。
次からRubyで書き出す処理の基本を解説します。
Fileオブジェクトを生成する
Fileクラスのopenメソッドにファイルのパスを指定することで、Fileオブジェクトを生成されます。そして、この処理で作成したFileオブジェクトにはファイル読み込み用のメソッドや書き込み用のメソッドが継承されており、Rubyのプログラムではそのようなメソッドを使ってファイルにアクセスします。
openメソッドの使い方
open( ファイルのパス, モード, パーミッション )
ファイルに書き込みするモードは”w”です。そして既にあるファイルに追記するモードの”a”もよく使われます。またパーミッションとはchmodで指定するファイルのパーミッションを整数で指定します。なお、openメソッドで開いたファイルは、closeメソッドによる閉じられます。openメソッドとcloseメソッドwpセットで利用してください。
書き込みでFileオブジェクトを生成する例
f = open( "out.txt", "w", perm=0666 ) f.close
Fileオブジェクトの書き込みメソッド
Fileオブジェクトに継承されているメソッドで、ファイルへの書き込みによく使われるのがwriteメソッドです。なお、実際にはwriteメソッドはIOクラスのメソッドで、引数に与えられた文字列をファイルポインタに書き込みます。
writeメソッドの書き方
Fileオブジェクト.write( 文字列 )
このメソッドは、書き込みに失敗した場合、begin~rescueによる例外処理を利用することが可能です。
writeメソッドの使用例
begin f = open( "out.txt", "w", perm=0666 ) f.write("ファイルに書き込みしました。\n") f.close rescue puts("ファイルの書き込みに失敗しました。\n") end
openメソッドのブロックで書き込む
先ほど紹介したopenメソッドは、生成したFileオブジェクトをブロックの中で使用してファイルに書き込む処理を作れます。なお、先ほどの例ではcloseメソッドでファイルを閉じていましたが、ブロック形式で記述した場合、ブロックの処理が終了すると、そのファイルは自動的にクローズされます。
ブロック形式の書き込みの例
begin open( "out.txt", "w", perm=0666 ) do |f| f.write("ファイルに書き込みしました。\n") end rescue puts("ファイルの書き込みに失敗しました。\n") end
Fileオブジェクトの応用
先ほど説明したようにプログラムからファイルにアクセスするにはファイルポインターを利用します。そしてRubyでファイルポインタに当たる変数がFileオブジェクトです。そのためFileオブジェクトをまるでファイルポインターのように使えます。次からFileオブジェクトの応用例を紹介します。
ファイルを追記する
ログファイルは、イベントが発生する度に既にあるテキストファイルの最後にメッセージが追加されます。このようなファイルの追記処理はファイルポインタで簡単に説明可能です。
通常ファイルに書き出す場合、ファイルポインタの先頭からデータを書き込みます。この場合、新規にファイルを作った場合は問題ありませんが、既にあるファイルの先頭からデータを書き込むと別の内容を上書きしてしまいます。
しかしファイルポインタを末尾に移動してから書き込みした場合、既にあるファイルの末尾からデータが追加されます。なお、ファイルポインタを末尾にするには、openメソッドでモードを”a”に設定して開いてください。
ファイル追記する例
begin f = open( "add.txt", "a", perm=0666 ) f.write("ファイルに追記しました。\n") f.close rescue puts("ファイルの追記に失敗しました。\n") end
ファイルの途中から追加する
先ほどファイルの末尾に追記する方法を紹介しましたが、ファイルポインタを特定の位置に変更し、そこからデータを書き込みすることも可能です。この場合、openメソッドで読み書き両用モード”r+”を使ってください。そしてRubyでファイルポインタの位置を変更するにはseekメソッドを使います。
seekメソッドの基本
seek( ファイルポインタを移動させる数、どこから移動させるか )
「どこから移動させるか」には次のいずれかを使う
IO::SEEK_SET ファイルの先頭から (デフォルト)
IO::SEEK_CUR 現在のファイルポインタから
IO::SEEK_END ファイルの末尾から
IO::SEEK_DATA offset 以降の次にデータがある位置へ
IO::SEEK_HOLE offset 以降の次にホールがある位置へ
ファイルポインタを移動させる例
begin f = open( "data.txt", "r+", perm=0666 ) f.seek(512, IO::SEEK_SET ) f.write("ファイルに追記しました。\n") f.close rescue puts("ファイルの追記に失敗しました。\n") end
これは、”data.txt”を”r+”で読み書き両用モードで開き、ファイルポインタを先頭から512バイト目に移動させてから文字を書き込みする例です。このように”r+”モードで開くことで、既にあるファイルの途中からでも書き込みできます。
まとめ
これまで説明したようにRubyのプログラムの中でデータをファイルに書き込みする場合は、ファイルポインタにあたるFileオブジェクトを作成し、そのメソッドを利用します。またファイルポインタは、ファイルの先頭から書き込みしたり、ファイルの末尾から書き込みすることも可能です。
ファイルへの書き込み処理は、ファイルポインタの仕組みを理解できれば難しくありません。特にRubyではFileオブジェクトを操作することで簡単に書き込み処理を作れるので、うまく活用できるようになりましょう。