ファイル名操作やファイルそのものの属性を操作したりする メソッドの集合体。
以下のものはクラスメソッドであり,オブジェクトの 確保なしにどのタイミングでも使える。
File.expand_path(file [, dir ])
ファイル名 file を絶対パスに展開する。
省略可能な第2引数 dir を指定するとそのディレクトリを
基準に展開する。先頭の ~
記号はホームディレクトリに
展開される。
File.expand_path(".zshrc", "~") => "/home/yuuji/.zshrc" File.expand_path(".zshrc", "~/../skel") => "/home/skel/.zshrc"
基準ディレクトリにあるファイル名を生成したいときには
ディレクトリ名とファイル名を文字列として連結するのではなく
File.expand_path()
を用いる方がよい。
File.basename(path)
File.basename(path, ext)
ファイル名 path のディレクトリ名を除いた部分を返す。 最後のスラッシュより後ろの部分。省略可能な第2引数 ext を指定するとファイル名の末尾がそれと一致した場合 のみ ext をさらに削除する。
File.dirname(path)
ファイル名 path のディレクトリ名部分を返す。
最後のスラッシュより前の部分。スラッシュを含まない場合は
"."
を返す。
File.basename
と組み合わせて,動作中Rubyプログラムの
格納ディレクトリとプログラム名を得るときに利用することが多い。
グローバル変数 $0
に動作中Rubyプログラムの名前が
入っていることを利用する。
mydir = File.dirname($0) myname = File.basename($0, ".rb") configfile = File.expand_path(".#{myname}rc", "~") scoredir = File.expand_path("../share/#{myname}", mydir) scorefile = File.expand_path("#{myname}.score", scoredir) # (不完全版でのちに修正あり)
一般的に,実行時に複数のファイルを利用するアプリケーション プログラムはインストールプレフィクス prefixを定め,
prefix/bin ... 実行ファイル prefix/lib ... ライブラリファイル prefix/man ... マニュアル prefix/share ... アーキテクチャ非依存ファイル(データなど)
というディレクトリ構造でインストールすることが多い。 プログラムの利用者がそのプログラムをどの prefix にインストールするかは自由なので,プログラムでは自分で 自分の prefix を検出し,データが格納されるべき 適切なディレクトリを探し出す必要がある。
File.chmod(mode, file)
file の属性を mode に変更する。 失敗したときは例外が発生する。モードは8進数で指定するのが 分かりやすい。
File.chmod(0755, "newprog.rb")
0(ゼロ)で始まる数値は8進数指定となる。
File.unlink(filename)
ファイルを削除する。厳密には,ファイルを消すわけではなく, ファイル名 filename の,実体との結合を削除する。
Unixファイルシステムではファイルの実体に結び付いている名前を
複数持てる。ファイルの新規作成では1つ目の名前が付き,
2つ目以降は ln(1)
で作れる。
touch hoge ls -l hoge -rw-r--r-- 1 yuuji wheel 0 Jun 8 06:43 hoge (第2フィールドの 1 はリンクカウント) ln hoge hero ls -l h* -rw-r--r-- 2 yuuji wheel 0 Jun 8 06:43 hero -rw-r--r-- 2 yuuji wheel 0 Jun 8 06:43 hoge ls -li h* 1510107 -rw-r--r-- 2 yuuji wheel 0 Jun 8 06:43 hero 1510107 -rw-r--r-- 2 yuuji wheel 0 Jun 8 06:43 hoge (ls -i オプションでinode番号も出力) ln hero heso ls -li h* 1510107 -rw-r--r-- 3 yuuji wheel 0 Jun 8 06:43 hero 1510107 -rw-r--r-- 3 yuuji wheel 0 Jun 8 06:43 heso 1510107 -rw-r--r-- 3 yuuji wheel 0 Jun 8 06:43 hoge (リンクカウントが3になる) date > hoge ls -li h* 1510107 -rw-r--r-- 3 yuuji wheel 29 Jun 8 06:43 hero 1510107 -rw-r--r-- 3 yuuji wheel 29 Jun 8 06:43 heso 1510107 -rw-r--r-- 3 yuuji wheel 29 Jun 8 06:43 hoge (すべて(29バイトに)変わる) rm hoge (hogeという名前だけを消す) ls -li h* 1510107 -rw-r--r-- 2 yuuji wheel 29 Jun 8 06:52 hero 1510107 -rw-r--r-- 2 yuuji wheel 29 Jun 8 06:52 heso
一般的に「ファイルを消す」という行為は,ファイルへの
1リンクを消しているに過ぎない。リンクカウント1のときに
unlink
するとファイルを参照できなくなる,つまり
実質的に「削除される」が,実体のデータが消えたわけではない。
参考: FreeBSD
rm コマンド の -P
オプション。
File.link(old, new)
old が指すファイルを指す新しいリンク new を作成する。同一のファイルに直接結び付けるリンクを ハードリンク という。
File.symlink(old, new)
old という名前を指す new
というシンボリックリンクを作成する。ln(1)
コマンドの
-s
オプションでもシンボリックリンクは作成できる。
ln -s foo bar ls -lF bar lrwxr-xr-x 1 yuuji wheel 3 Jun 8 07:23 bar@ -> foo
bar
というファイル名へのアクセスは
foo
へのアクセスに変換される。もちろん foo
がなければアクセスは失敗する。
ls foo ls: foo: No such file or directory cat bar cat: bar: No such file or directory date > foo cat bar Mon Jun 8 07:26:34 JST 2011 (fooがあればbarへのアクセスも成功)
File.rename(from, to)
from というファイル名を to に変える。 to という名前で別のファイルが存在するときは 上書きされる。失敗すると例外が発生する。
File.stat(filename)
filename の情報を取得する。 File::Stat オブジェクトが返る。
以下のメソッドは IOクラスの非クラスメソッドである。既に開いているIOオブジェクト から利用する。
seek(offset [, whence])
ファイルポインタを offset だけ移動する。 省略可能な第2引数で移動の基準位置を指定する。
IO::SEEK_SET | ファイルの先頭 |
IO::SEEK_CUR | 現在のファイルポインタ位置 |
IO::SEEK_END | ファイルの末尾 |
デフォルトは IO::SEEK_SET
。
rewind
ファイルポインタを先頭に移動する。
pos
tell
現在のファイルポインタ位置を返す。
flush
IOポートの内部バッファをフラッシュする。STDOUT
のようにバッファリングされるIOポートへの出力をフラッシュすることで
その時点までのデータが書き込まれる。
fsyncが必要な場合もある。
sync
出力同期モードを真偽値で指定する。
IO.sync=true
なら同期モード,
IO.sync=false
とすると非同期(バッファリングされる)モードになる。
ディレクトリを操作したり,あるディレクトリに存在する ファイル名一覧を得るためのメソッド。
Dir[pattern]
Dir.glob(pattern)
pattern にシェルパターンとしてマッチする ファイル名一覧を含む配列を返す。
Dir.entries(dir)
ディレクトリ dir の持つファイルエントリを
配列として返す。dir ディレクトリを基準とした
ファイル名なのでアクセスする場合は dir に
Dir.chdir
するか,File.expand_path
で絶対パスに展開する必要がある。
#!/usr/bin/env ruby checkdir = ARGV.shift || "." printf("(1)ここは%s\n", Dir.pwd) printf(%Q/"%s" ディレクトリのエントリ一覧\n/, checkdir) files = Dir.entries(checkdir) printf(%Q/先頭要素は必ず "%s"\n/, files.shift) printf(%Q/2番目要素は必ず "%s"\n/, files.shift) print("残りは登録順: ") $KCODE=ENV["LC_ALL"] || ENV["LANG"] || 'e' p files puts "-"*15+"サイズ一覧"+"-"*15 files.each do |f| file = File.expand_path(f, checkdir) size = File.stat(file).size printf("%-30s %6d\n", f, size) end
Dir.pwd
Dir.getwd
現行Rubyプロセスのカレントディレクトリのフルパスを返す。
Dir.chdir(dir)
カレントディレクトリを dir に変更する。 後ろにブロックを指定するとブロック実行中のみカレントディレクトリを 変更する。
#!/usr/bin/env ruby printf("(1)ここは%s\n", Dir.pwd) Dir.chdir(File.expand_path("~")) do printf("(2)ここは%s\n", Dir.pwd) end printf("(3)ここは%s\n", Dir.pwd)
実行すると以下のようになる。
./pwd.rb
(1)ここは/home/yuuji/Ruby
(2)ここは/home/yuuji
(3)ここは/home/yuuji/Ruby
Dir.mkdir(newdir [,
mode ])
新しいディレクトリ newdir を作成する。
省略可能な第2引数 mode を指定すると,
その時点の umask 値でマスクした値(mode& ~umask
)
のパーミッション値となる。
Dir.rmdir(dir)
ディレクトリ dir を削除する。成功すると0が返され, 失敗すると例外が発生する。
ファイルはリンクカウント1のときの名前が消えても,そのファイルへの
アクセスがある限りファイルシステムの一領域を占め続ける。
プログラム中で利用する一時ファイルを作成後,すぐに
unlink
しても close
するまではアクセスし続けられる。
#!/usr/bin/env ruby tmpfile = ARGV.shift || "00TEMPFILE" tmpdir = File.dirname(tmpfile) open(tmpfile, "w+") do |tf| 1.upto(10) do |lineno| tf.printf("これは%02d行目\n", lineno) end tf.puts "-"*1024*1024 # 1MBのダミーデータ tf.flush # バッファを書き込み tf.rewind # ファイルポインタを先頭に system "ls -lF #{tmpfile}" STDERR.puts "改行を押すとこのファイルを消します。" STDIN.gets File.unlink(tmpfile) system "ls -lF #{tmpfile}" STDERR.puts "closeする前のこのディスクの空き容量:" system "df -k #{tmpdir}" STDERR.puts "1行目から読みます。" STDERR.puts "別の端末でlsして#{tmpfile}がないことを確認しましょう。" 10.times do |l| print tf.gets sleep 1 end end STDERR.puts "closeされたあとのこのディスクの空き容量:" system "sync; sync; df -k #{tmpdir}"