From: Koji Arai Date: 2002-11-17T02:36:46+09:00 Subject: [ruby-list:36497] cacheout.rb 新井です。 Perl には、昔から cacheout.pl というライブラリ(今は FileCache.pm)があるんですが、これ Ruby にも欲しくないですか? 過去3度は欲しいと思った(すくない?)のですが、4度目にして cacheout.pl を移植しました(即席なのでバグがありそう)。 念のため、cacheout.pl というのは、システムの上限を気にせずに 出力ファイルをたくさんオープンできる(ように見せる)ライブラリ です。 RAA を検索したら Ruby/Cache というのをおくじさんが作ってらっ しゃるようですが、汎用的なものなので今回の目的にはあわないかな? # あまり調べなかったですが。 というわけで、提案でした。 class FileCache def initialize(maxopen = 10) @maxopen = maxopen @numopen = 0 @isopen = {} # {filename => [aFile, @seq], ...} @seq = 0 @saw = {} end def open(file) if @isopen[file].nil? @numopen += 1 if @numopen > @maxopen lru = @isopen.sort {|a,b| a[1][1] <=> b[1][1]}.slice(0, @maxopen / 3) @numopen -= lru.size lru.each {|name, (f, seq)| @isopen.delete(f.path) f.close } end @isopen[file] = [] @isopen[file][0] = File.open(file, @saw[file].nil? ? "w" : "a") @saw[file] ||= 0 @saw[file] += 1 end @isopen[file][1] = @seq += 1 @isopen[file][0] end def close @isopen.each {|name, (f, seq)| f.close } @isopen.clear initialize(@maxopen) self end end # 以下は、サンプルのためのサンプル if $0 == __FILE__ File.open("/tmp/foo", "w") {|f| 1000.times {|i| f.printf("file%03d %d\n", rand(100), i) } } # /tmp/foo # foo001 0 # foo099 1 # foo050 2 # foo001 3 # : # : cacheout = FileCache.new(10) File.open("/tmp/foo") {|f| while line = f.gets file, number = line.split cacheout.open(file).puts number end } end -- 新井康司 (Koji Arai)