Rubyでファイル操作

ファイル・ディレクトリの操作は、Fileクラス、Dirクラス、FileUtilsモジュールを使う。

ディレクトリ操作

ファイル操作

ディレクトリ階層の操作

ファイル内容の読み込みと書き込み


ルートディレクトリとカレントディレクトリ

ディレクトリの階層構造

通常、あらゆるデータはファイルとして管理される。複数のファイルをまとめる入れ物がディレクトリで、そのディレクトリも他のディレクトリの中に格納できる。こうしてディレクトリは階層構造となっている。階層の区切りは/(スラッシュ)で表現し、「/A/B/C」というように実際のディレクトリ階層を表す。

ルートディレクトリ

一番上の階層をルートディレクトリといい、左端の/で表す。階層の区切りも/なので、「/A/B/C」なら一番左の/がルートディレクトリ。

カレントディレクトリ

プログラムを実行しているとき、特にファイル・ディレクトリを操作するときは、「今どこのディレクトリで作業しているか」というカレントディレクトリに注目する必要がある。

絶対パスと相対パス

操作対象のファイル・ディレクトリの位置のことをパスという。ルートディレクトリからの位置を絶対パス(フルパス)といい、カレントディレクトリからの位置を相対パスという。カレントディレクトリを.、一つ上の階層を..で表す。

# /親/子1/孫1 /親/子2/孫2 という階層の場合

# カレントディレクトリ孫1の場合の、二つ上の階層(ルートディレクトリ)
../../

# カレントディレクトリ孫1の場合の、孫2
../子2/孫2

カレントディレクトリの確認: Dir.pwdメソッド

カレントディレクトリの確認はBashではpwdコマンド、RubyではDir.pwdメソッドを使う。

# Bash
pwd
# Ruby
puts Dir.pwd

どちらも出力は「/home/ユーザ/ruby」などと実行時の絶対パス。


カレントディレクトリ変更: Dir.chdirメソッド

プログラム中でカレントディレクトリを変更するのはDir.chdirメソッド。プログラム中の変更なので、終了すると元のシェルでは元のディレクトリのまま。

Dir.chdir("パス")

ディレクトリの内容確認: Dir.globメソッド

Dir.globメソッドは、ワイルドカードなどを使ってディレクトリの内容を検索できる。

# .ファイルを除いたファイル・ディレクトリ一覧
puts Dir.glob("*")

# 再帰的に検索
puts Dir.glob("**/*")

# .ファイル
puts Dir.glob(".*")

# .rbファイル
puts Dir.glob("*.rb")

# .rbファイルと.txtファイル
puts Dir.glob(["*.rb", "*.txt"])

# 拡張子が2文字
puts Dir.glob("*.??")

# aかAで始まるファイル
puts Dir.glob("[aA]*")

ディレクトリ作成: Dir.mkdirメソッド

Dir.mkdir("パス")

ディレクトリ削除: Dir.rmdirメソッド

Dir.rmdirメソッドは空のディレクトリを削除できる。

Dir.rmdir("パス")

ファイル名変更: File.renameメソッド

File.rename("変更前パス", "変更後パス")

ファイル削除: File.deleteメソッド

File.delete("パス")

ディレクトリを再帰的にコピー: FileUtils.cp_rメソッド

ディレクトリを再帰的にコピーするには、fileutilsライブラリのFileUtils.cp_rメソッド。

require "fileutils"
FileUtils.cp_r("コピー元パス", "コピー先パス")

2番目の引数のディレクトリが既に存在する場合は、その下にコピーとなる。


ディレクトリを移動: FileUtils.mvメソッド

ディレクトリを移動(名前変更)するには、fileutilsライブラリのFileUtils.mvメソッド。

require "fileutils"
FileUtils.mv("移動前パス", "移動先パス")

2番目の引数のディレクトリが既に存在する場合は、その下に移動する。


ディレクトリを再帰的に削除: FileUtils.rm_rfメソッド

ディレクトリを再帰的にコピーするには、fileutilsライブラリのFileUtils.rm_rfメソッド(例外発生でも処理継続)か、FileUtils.rm_rメソッド(例外発生で処理中断)。

require "fileutils"
FileUtils.rm_rf("パス")

階層のあるディレクトリを一気に作成: FileUtils.mkdir_pメソッド

ディレクトリ作成で、Dir.mkdirメソッドでは親ディレクトリが存在している必要があるが、FileUtils.mkdir_pメソッドは上位ディレクトリも含めて一気に作成できる。

require "fileutils"
FileUtils.mkdir_p("a/b/c")

ファイル全体を読み込む: File.readメソッド

ファイル全体を一気に読み込むだけなら、File.readメソッド。

print File.read("パス")

ファイルを開く: File.openメソッド

ファイルを一行ずつ読み込んで何か処理したい場合は、まずはFile.openメソッドでファイルを開いてから。2番目の引数は読み書きのモードで、

処理が終わったらcloseメソッドでファイルを閉じる。

# ファイルオブジェクトを得る
file = File.open("パス", "r+")

# 処理が終わったら閉じる
file.close

ファイルを一行ずつ読み込む: getsメソッドとeachメソッド

File.openメソッドでファイルを開いてから、getsメソッドやeachメソッドで一行ずつ読み込んで何か処理する。

getsメソッド

file = File.open("パス")
# 最終行まで読み込んだらnil(false)が返り、繰り返し終了となる
while line = file.gets
  print line
end
file.close

eachメソッド

file = File.open("パス")
file.each do |line|
  print line
end
file.close

ファイルに追記: putsメソッド

ファイルに追記するならputsメソッド。

file = File.open("パス", "a")
file.puts("追記データ")
file.close