我一直在使用Rails应用程序的日志查看器,并发现我需要从底部到顶部读取大约200行的日志文件,而不是默认的从上到下.
日志文件可能会相当大,所以我已经尝试排除了IO.readlines(“log_file.log”)[ – 200 ..- 1]的方法.
解决方法
执行此操作同样适用于巨大文件的唯一正确方法是从最后一次读取n个字节,直到您需要的行数为止.这实际上是Unix尾部的工作原理.
IO#tail(n)的一个示例实现,它返回最后的n行作为数组:
class IO TAIL_BUF_LENGTH = 1 << 16 def tail(n) return [] if n < 1 seek -TAIL_BUF_LENGTH,SEEK_END buf = "" while buf.count("\n") <= n buf = read(TAIL_BUF_LENGTH) + buf seek 2 * -TAIL_BUF_LENGTH,SEEK_CUR end buf.split("\n")[-n..-1] end end
实现有点天真,但是一个快速的基准测试显示了这个简单的实现可以做出的可笑的区别(使用yes> yes.txt生成的〜25MB文件进行测试):
user system total real f.readlines[-200..-1] 7.150000 1.150000 8.300000 ( 8.297671) f.tail(200) 0.000000 0.000000 0.000000 ( 0.000367)
基准代码:
require "benchmark" FILE = "yes.txt" Benchmark.bmbm do |b| b.report "f.readlines[-200..-1]" do File.open(FILE) do |f| f.readlines[-200..-1] end end b.report "f.tail(200)" do File.open(FILE) do |f| f.tail(200) end end end
当然,other implementations已经存在.我没有尝试过,所以我不能告诉你哪个是最好的.