【问题标题】:How to read a file block in Rails without read it again from beginning如何在 Rails 中读取文件块而不从头开始再次读取
【发布时间】:2015-12-02 10:27:49
【问题描述】:

我有一个不断增长的文件(日志),需要按块读取。 我通过 Ajax 进行调用以获取指定数量的行。 我使用 File.foreach 来读取我想要的行,但它总是从头开始读取,我只需要直接返回我想要的行。

示例伪代码:

 #First call:
  File.open and return 0 to 10 lines

 #Second call:
  File.open and return 11 to 20 lines

 #Third call:
  File.open and return 21 to 30 lines

 #And so on...

有没有办法做到这一点?

【问题讨论】:

标签: ruby-on-rails ruby ajax file file-read


【解决方案1】:

解决方案 1:读取整个文件

这里建议的解决方案:
https://stackoverflow.com/a/5052929/1433751

..在您的情况下不是一个有效的解决方案,因为它要求您从文件中读取每个 AJAX 请求的所有行,即使您只需要日志文件的最后 10 行。

这是对时间的极大浪费,而且在计算方面,求解时间(即以大小为 N 的块处理整个日志文件)接近指数求解时间。

解决方案 2:寻找

由于您的 AJAX 调用请求顺序行,我们可以通过使用IO.seekIO.pos在读取之前寻找正确的位置来实现更有效的方法。

这要求您在返回请求的行的同时将一些额外的数据(最后一个文件位置)返回给 AJAX 客户端。

然后,AJAX 请求变成这种形式的函数调用request_lines(position, line_count),这使服务器能够在读取请求的行数之前IO.seek(position)

这是解决方案的伪代码:

客户端代码

LINE_COUNT = 10
pos = 0

loop {
  data = server.request_lines(pos, LINE_COUNT)
  display_lines(data.lines)
  pos = data.pos
  break if pos == -1  # Reached end of file
}

服务器代码

def request_lines(pos, line_count)
  file = File.open('logfile')

  # Seek to requested position
  file.seek(pos)

  # Read the requested count of lines while checking for EOF
  lines = count.times.map { file.readline if !file.eof? }.compact

  # Mark pos with -1 if we reached EOF during reading
  pos = file.eof? ? -1 : file.pos
  f.close

  # Return data
  data = { lines: lines, pos: pos }
end

【讨论】:

  • 感谢您的快速回复。最后一个解决方案解决了我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-10
  • 1970-01-01
  • 2020-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多