问题描述
|
我有一个看起来像这样的大文件:
7
bla1
blala
blabla
blab
blals
blable
bla
more here..
第一个数字表明我将拥有多少个值。问题是,我只想直接指向第11行(文本\“ more here .. \”),而不必之前读取所有这些值。就我而言,我有很多数字,因此必须对其进行优化。
你会推荐我一些东西吗?
解决方法
您可以制作类似文件的内容,跳过前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#seek随机访问文件。
这种方法的问题在于它将仅以指定的字节偏移量而不是行偏移量访问数据。如果您的文件可以在文件的开头给出列表结束处的字节偏移量,那么您可以使用它。
, 这是一种优雅的方式,虽然可能需要立即将整个文件加载到内存中,但效率可能不高。
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