我有一个巨大的文件,看起来像这样:
7
bla1
blala
blabla
blab
blals
blable
bla
more here..
第一个数字告诉我会有多少值。问题是,我只想直接指向第11行(文本"more here.."),而不必之前读取所有这些值。在我的情况下,我有大量的数字,所以必须对其进行优化。
你能给我推荐点什么吗?
您可能会使用File#seek来随机访问该文件。
这种方法的问题在于,它只访问指定字节偏移量的数据,而不是行偏移量。如果您的文件可以将文件开头的字节偏移量提供给列表结束的位置,那么您可以使用它。
你可以制作这样的文件,跳过前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
如果您只想在文件的行中向前迭代,那么这很容易做到。然而,如果您想准确地模仿File
或IO
接口(但请参见Delegate
),尤其是如果您想支持倒回文件的伪开头,这将变得非常困难。
这里有一种很好的方法,可能效率不高,因为它需要一次将整个文件加载到内存中。
File.readlines(file_path)[10..-1] # indexing starts from 0
我认为你不会有比这更高效的了,因为你已经读取了文件中的字节来找出什么是"行"。
f = File.open('./data')
(f.readline.to_i + 2).times { f.readline }
p f.readline