それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Rubyで巨大ファイルを読み込むときに進捗率を表示したい

Rubyを使ってバッチ処理や集合演算をするときに、ファイルをどこまで読み込んだかパーセント表示したい。表示しておかないとどこまで処理しているかが分からないので不安になる。処理状況を表示する。

File#linenoを使えばいいかと思ったが、File#linenoはFile#readやFile#readlinesなどを一度実行しないと、ファイルの行数が分からないようなので。。。ポインタの位置から進捗を見ることにする。

進捗率の表示

進捗を%表示で見せるサンプル
open filename do |f|
  size = File.size f.path
  f.each_line do |line|
    #do something...
    $stderr.print sprintf("%.3f%",f.tell.to_f/size.to_f*100)+"\r"
  end
end

解説:

  • File.sizeでファイルサイズを取得する
  • File#tellで現在の位置を取得する
  • "\r"を使うことで書き出しを固定

もちろんこれを応用すればコンソールにプログレスバーを作れるわけだが。さすがに、そこまでは不要だと思うのだが。自己満足のために作ってみた

プログレスバー(コンソール)

GUIは別スレッドで画面更新処理が必要なので、コンソールのみ。

def show_progress_bar(progress)
	print "#"*progress.to_i, "-"*(100-progress.to_i),":",sprintf("%.3f%",progress.to_f),"%\r"
end
open filename do |f|
  size = File.size f.path
  f.each_line do |line|
    #do something...
    show_progress_bar f.tell.to_f/size.to_f*100
  end
end

Perlのいいとこ取りのおかげで簡単にかける。Ruby素敵。