2015-12-02 60 views
2

我有一个正在增长的文件(日志),需要按块读取。 我使用Ajax进行调用以获取指定数量的行。 我使用File.foreach来读取我想要的行,但它始终从头读取,我只需直接返回我想要的行。如何在Rails中读取文件块而不从头再读取

示例伪代码:

#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... 

反正有使这个?

+1

看看这里:http://stackoverflow.com/a/5052929/1433751 这应该回答你的问题 – Noxx

回答

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 
} 

Server代码

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 
+0

谢谢你fo快速回应。最后的解决方案解决了我的问题 – koxta