ファイル・ディレクトリの操作は、File
クラス、Dir
クラス、FileUtils
モジュールを使う。
通常、あらゆるデータはファイルとして管理される。複数のファイルをまとめる入れ物がディレクトリで、そのディレクトリも他のディレクトリの中に格納できる。こうしてディレクトリは階層構造となっている。階層の区切りは/
(スラッシュ)で表現し、「/A/B/C」というように実際のディレクトリ階層を表す。
一番上の階層をルートディレクトリといい、左端の/
で表す。階層の区切りも/
なので、「/A/B/C」なら一番左の/がルートディレクトリ。
プログラムを実行しているとき、特にファイル・ディレクトリを操作するときは、「今どこのディレクトリで作業しているか」というカレントディレクトリに注目する必要がある。
操作対象のファイル・ディレクトリの位置のことをパスという。ルートディレクトリからの位置を絶対パス(フルパス)といい、カレントディレクトリからの位置を相対パスという。カレントディレクトリを.
、一つ上の階層を..
で表す。
# /親/子1/孫1 /親/子2/孫2 という階層の場合
# カレントディレクトリ孫1の場合の、二つ上の階層(ルートディレクトリ)
../../
# カレントディレクトリ孫1の場合の、孫2
../子2/孫2
カレントディレクトリの確認はBashではpwd
コマンド、RubyではDir.pwd
メソッドを使う。
# Bash
pwd
# Ruby
puts Dir.pwd
どちらも出力は「/home/ユーザ/ruby」などと実行時の絶対パス。
プログラム中でカレントディレクトリを変更するのはDir.chdir
メソッド。プログラム中の変更なので、終了すると元のシェルでは元のディレクトリのまま。
Dir.chdir("パス")
Dir.glob
メソッドは、ワイルドカードなどを使ってディレクトリの内容を検索できる。
?
任意の一文字*
0字以上の任意の文字列**/
再帰的検索(すべての下層のディレクトリを検索)[]
角括弧内の文字のどれかに一致# .ファイルを除いたファイル・ディレクトリ一覧
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.rmdir
メソッドは空のディレクトリを削除できる。
Dir.rmdir("パス")
File.rename("変更前パス", "変更後パス")
File.delete("パス")
ディレクトリを再帰的にコピーするには、fileutils
ライブラリのFileUtils.cp_r
メソッド。
require "fileutils"
FileUtils.cp_r("コピー元パス", "コピー先パス")
2番目の引数のディレクトリが既に存在する場合は、その下にコピーとなる。
ディレクトリを移動(名前変更)するには、fileutils
ライブラリのFileUtils.mv
メソッド。
require "fileutils"
FileUtils.mv("移動前パス", "移動先パス")
2番目の引数のディレクトリが既に存在する場合は、その下に移動する。
ディレクトリを再帰的にコピーするには、fileutils
ライブラリのFileUtils.rm_rf
メソッド(例外発生でも処理継続)か、FileUtils.rm_r
メソッド(例外発生で処理中断)。
require "fileutils"
FileUtils.rm_rf("パス")
ディレクトリ作成で、Dir.mkdir
メソッドでは親ディレクトリが存在している必要があるが、FileUtils.mkdir_p
メソッドは上位ディレクトリも含めて一気に作成できる。
require "fileutils"
FileUtils.mkdir_p("a/b/c")
ファイル全体を一気に読み込むだけなら、File.read
メソッド。
print File.read("パス")
ファイルを一行ずつ読み込んで何か処理したい場合は、まずはFile.open
メソッドでファイルを開いてから。2番目の引数は読み書きのモードで、
"r"
既存ファイルの読込専用(引数省略した場合も)"r+"
既存ファイルの読込と書込"w"
書込専用で新規作成、既存なら内容が消える"w+"
"w"に加えて読込も"a"
追記用"a+"
追記と読込用
処理が終わったらclose
メソッドでファイルを閉じる。
# ファイルオブジェクトを得る
file = File.open("パス", "r+")
# 処理が終わったら閉じる
file.close
File.open
メソッドでファイルを開いてから、gets
メソッドやeach
メソッドで一行ずつ読み込んで何か処理する。
file = File.open("パス")
# 最終行まで読み込んだらnil(false)が返り、繰り返し終了となる
while line = file.gets
print line
end
file.close
file = File.open("パス")
file.each do |line|
print line
end
file.close
ファイルに追記するならputs
メソッド。
file = File.open("パス", "a")
file.puts("追記データ")
file.close