用Ruby读取选择性文件

时间:2011-06-14 13:07:48

标签: ruby seek

我有一个巨大的文件,如下所示:

7

bla1
blala
blabla
blab
blals
blable
bla

more here..

第一个数字表示我将拥有多少个值。问题是,我只想直接指向第11行(文本“更多这里......”),而不必先阅读所有这些值。在我的情况下,我有大量的数字,所以必须进行优化。

你能推荐我什么吗?

4 个答案:

答案 0 :(得分:5)

您可以使用File#seek随机访问该文件。

该方法的问题在于它只访问指定字节偏移量的数据 - 而不是行偏移量。如果您的文件可以将文件开头的字节偏移量提供给列表完成的位置,那么您可以使用它。

答案 1 :(得分:3)

你可以创建一些类似于跳过前N行的文件:

SkipFile.open("/tmp/frarees") do |ln|
  puts ln                                   # "more here.." and so on
end

puts SkipFile.new("/tmp/frarees").readline  # "more here.."

像这样:

class SkipFile
  def self.open(fn, &block)
    sf = SkipFile.new(fn)
    return sf unless block
    sf.each(&block)
  end

  def initialize(fn)
    @f = File.open(fn)
    skip = @f.readline.to_i     # Skip N lines as prescribed by the file
    skip.times { @f.readline }  # this could be done lazily
  end

  def each(&block)
    @f.each(&block)
  end

  def readline
    @f.readline
  end
end

如果您只想在文件行中向前迭代,则很容易做到。但是,如果您想完全模仿FileIO界面(但请参阅Delegate),尤其是如果您希望支持可重新回退到文件的虚假启动,则会变得非常艰难

答案 2 :(得分:1)

这是一种优雅的方式,可能效率不高,因为它需要一次将整个文件加载到内存中。

File.readlines(file_path)[10..-1] # indexing starts from 0

答案 3 :(得分:1)

我认为你不会比这更有效率,因为你已经读过文件中的字节来弄清楚什么是“线”。

f = File.open('./data')
(f.readline.to_i + 2).times { f.readline }
p f.readline