作者热门文章
- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我一直在为 Rails 应用开发日志查看器,发现我需要从下到上阅读大约 200 行的日志文件,而不是默认的从上到下阅读。
日志文件可能会变得非常大,所以我已经尝试并排除了 IO.readlines("log_file.log")[-200..-1] 方法。
有没有其他方法可以在不需要插件或 gem 的情况下在 Ruby 中反向读取文件?
最佳答案
执行此操作且适用于大型文件的唯一正确方法是从末尾一次读取 n 个字节,直到获得所需的行数。这基本上就是 Unix tail
的工作方式。
IO#tail(n)
的示例实现,它将最后的 n
行作为 Array
返回:
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已经存在。我没有尝试过,所以我不能告诉你哪个最好。
关于ruby-on-rails - 如何在 Ruby 中从下到上读取文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3024372/
我是一名优秀的程序员,十分优秀!