ruby-on-rails - 如何在 Ruby 中从下到上读取文件?

标签 ruby-on-rails ruby file-io

我一直在为 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/

相关文章:

ruby-on-rails - 使用实例变量或帮助程序管理用户权限

ruby-on-rails - PG::错误:错误:新编码(UTF8)不兼容

ruby-on-rails - 如何在 has_many :through 中找到不同的值

arrays - `+=` block 内的 `<<` 和 `each_with_object` 之间的区别

c - 如何用 fwrite() 覆盖偏移量 Y 上的 X 个字节?

matlab - 在Matlab中读取txt文件

ruby-on-rails - 如何覆盖 ruby​​ 中的 [] 括号?

ruby-on-rails - 使用 Rails 4 对象将 PSQL 查询转换为工作

c - 将参数传递给 pthread 会导致重复 C

ruby-on-rails - 显示 View 中的 "Previous post"和 "Next post"链接(嵌套资源)