2011-06-14 76 views
3

讀我有一個巨大的文件,看起來像這樣:選擇文件中的Ruby

7 

bla1 
blala 
blabla 
blab 
blals 
blable 
bla 

more here.. 

第一個號碼告訴我有多少價值都會有。事情是,我只是想直接指向第11行(文本「更多這裏..」),而不必閱讀所有這些值之前。就我而言,我有很多數字,所以它必須進行優化。

你會推薦我一些東西嗎?

+1

你有沒有考慮過將它導入到SQLite數據庫(或像GDBM這樣的鍵值數據庫)?然後,你只需要做一次醜陋的全面掃描。文本文件和隨機訪問不是朋友。 – 2011-06-14 15:33:22

回答

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),並且特別是要支持將可回溯性恢復爲您的文件的假開始時,它會變得非常艱難。

1

下面是一個很好的方式來做到這一點,雖然它可能不是很有效,但它需要將整個文件一次加載到內存中。

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

您可以使用File#seek來隨機訪問該文件。

該方法的問題是,它只會訪問指定字節偏移處的數據 - 而不是行偏移量。如果你的文件可以在文件開始時將字節偏移量提供給列表完成的地方,那麼你可以使用它。

+0

是的,我知道,事情是,我不能計算字節偏移量(不同的行大小),我只給了行數:( – frarees 2011-06-14 13:54:41

1

我不認爲你會得到比這更有效的,因爲你會讀取文件中的字節來找出什麼是「線」。

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