たのしいRuby 復習-HDD内のサイズが大きいファイルの一覧を求める
ちょっとしたプログラムが必要なとき最近はRubyを使うことが多いわけですが、同じようなことしかしないので忘却が激しい。都度ヘルプを見てるわけですが、仕事なのでゆっくりというわけにも行かないので たのしいRuby 第2版 Rubyではじめる気軽なプログラミング を読み返す。
- 第1章〜第14章
で、本題のプログラム
- Dirクラスを使って自前で再帰検索
- Dir.openが多重になるのを回避する
の順で作成。
一方たのしいRubyにはDir.Glob("**/*")が載っていたので試してみたが、どうもこれは一旦すべてのファイルをリストアップして配列を作るようで、ちょっと気持ちが悪い。
2009年6月2日修正
FileTest.size()を例外処理で包んでおかないと、これが例外はいたとき一気に処理が飛ばされるのを修正。なんか出力されるファイルが少ないと思って気づく orz
#! ruby -Ks MAXNUM = 100 class InfoList # ファイル情報を扱うクラス class Info attr_reader :name, :size # ファイル名とサイズでインスタンス作成 def initialize(name, size) @name = name @size = size end # 表示用 def to_s "#{size}\t#{name}" end end # リストに含まれる最大ファイル数を指定 def initialize(maxnum) @maxnum = maxnum @data = Array.new end # リストに追加 def add(name, size) info = Info.new(name, size) index = -1 @data.each_with_index do |d, i| # 挿入位置を検索 if info.size > d.size index = i break end end if index == -1 @data << info # リストが空、もしくはリスト内のものよりサイズが小さい else @data[index, 0] = info # リストへ挿入 end if @data.size > @maxnum # 最大数を越えていれば末尾を削除 @data.pop end end # リストを表示 def show @data.each do |d| puts d end puts "" end end # ディレクトリを検索 def traverse(top, dirs, list) Dir.open(top).each do |name| path = top + name next if name == "." || name == ".." if FileTest.directory?(path) # ディレクトリのときは保存 dirs << path + "\\" else # ファイルはリストへ加える begin list.add(path, FileTest.size(path)) rescue =>e puts e.message end end end rescue =>e puts e.message end # 引数チェック if ARGV.size == 1 top = ARGV[0] maxnum = MAXNUM elsif ARGV.size == 2 top = ARGV[0] maxnum = ARGV[1].to_i else puts "usage: ruby filelist.rb top_dir [max_list]" exit end # 指定ディレクトの末尾に\を加える if top[-1] != "\\"[0] top += "\\" end list = InfoList.new(maxnum) dirs = [top] while dir = dirs.pop traverse(dir, dirs, list) end # 結果表示 list.show