![](/img/trans.png)
[英]Use ruby mp3info to read mp3 ID3 from external site (without loading whole file)
[英]Is there a way to seek through a file without loading the whole thing into an array?
這有效:
f = File.new("myfile").readlines
f[0] #=> "line 1"
f[21] #=> "line 22"
但是,如果我有一個非常大的文件,只需要閱讀幾行。 有沒有可能尋找特定的行並在Ruby中讀取它們,而無需將文件加載到數組中?
我知道IO流,在那里(如在stdin的情況下)你不能隨機搜索流。 當然必須有一種方法可以在不加載整個文件的情況下執行此操作。
不要忽略IO
類。 IO::foreach
是返回Enumerator的方法之一,可以進行延遲計算。
IO#each_line
也是另一個將返回枚舉器的人。
在Ruby 2.0中,我們可以調用.lazy
並使用那些方法,除了zip和cycle,它們允許我們遍歷枚舉而不將整個文件放入內存。
為此,您可以使用each_line
迭代器,結合with_index
來獲取當前行的行號(從0開始計算):
File.open('myfile') do |file|
file.each_line.with_index do |line, lineno|
case lineno
when 0
# line 1
when 21
# line 22
end
end
end
通過使用open
,將塊傳遞給它而不是new
,可以保證在塊執行結束時正確關閉文件。
更新 with_index
方法接受一個可選參數來指定要使用的起始索引,因此上面的代碼可以更好地編寫如下:
file.each_line.with_index(1) do |line, lineno|
case lineno
when 1
# line 1
end
end
我使用過Jack和toro2k的答案(大致相同的答案),但是根據我自己的用例進行了修改。 我可能想要的地方:打開一個文件,並尋找多個隨機行,其中順序可能並不總是順序的。 這就是我提出的(抽象的):
class LazyFile
def initialize(file)
@content = File.new(file)
end
def [](lineno)
@content.rewind if @content.lineno > lineno
skip = lineno - @content.lineno
skip.times { @content.readline }
@content.readline
end
end
file = LazyFile("myfile")
file[1001]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.