【发布时间】:2010-11-27 18:23:23
【问题描述】:
如何读取文件的前一行。与 IO.gets 相反。我最初想将 IO.lineno 设置为我想读取的行号,但这并不像预期的那样工作。您实际上是如何阅读上一行的?
【问题讨论】:
-
我也在 comp.lang.ruby 上看到了这个问题——如果你在那里得到了一个好的答案,请成为一个好公民并更新这个页面。
如何读取文件的前一行。与 IO.gets 相反。我最初想将 IO.lineno 设置为我想读取的行号,但这并不像预期的那样工作。您实际上是如何阅读上一行的?
【问题讨论】:
有几种方法,这取决于您掌握的信息量。 如果你知道你读到的最后一行的长度,你可以采取最简单的方法,那就是
# assume f is the File object
len = last_line_length
f.seek -len, IO::SEEK_CUR
当然,如果不向您提供这些信息,事情就会变得不那么美好。您可以使用与上述相同的方法向后走(一次一个字节),直到您遇到换行符或取 lineno 并从头开始阅读。类似的东西
lines = f.lineno
f.rewind
(lines - 1).times { f.gets }
但是,据我所知,没有直接机制可以仅使用 go back 1 N 其中N 代表一条线。
顺便说一句,您应该知道,虽然您可以写信给File.lineno,但这样做实际上不会影响文件中的位置,而且还会破坏该点之后读取的变量的准确性。
【讨论】:
一个简单的方法是记住你读过的上一行:
prev = nil
File.foreach('_vimrc') do |line|
p [line, prev] # do whatever processing here
prev = line
end
【讨论】:
在comp.lang.ruby 上看到了一个很好的建议——使用 IO.tell 来跟踪文件中每一行的位置,以便您可以直接查找它:
File.open "foo" do |io|
idx = [io.tell]
while l = io.gets
p l
idx << io.tell
end
end
【讨论】:
Elif gem 有一个gets 方法,它与IO.gets 相反。
$ sudo gem install elif
$irb
require "elif"
last_syslog = Elif.open('/var/log/syslog') { |file| file.gets }
【讨论】: