2014-05-04 93 views
3

我已經寫了一些CSV文件,壓縮它,使用此代碼:讀取壓縮csv文件上即時

arr = (0...2**16).to_a 
File.open('file.bz2', 'wb') do |f| 
    writer = Bzip2::Writer.new f 
    CSV(writer) do |csv| 
    (2**16).times { csv << arr } 
    end 
    writer.close 
end 

我想讀這個CSV bzip2ed文件(用bzip2壓縮的CSV文件) 。這些文件未壓縮的樣子:

1,2 
4,12 
5,2 
8,7 
1,3 
... 

所以,我想這個代碼:

Bzip2::Reader.open(filename) do |bzip2| 
    CSV.foreach(bzip2) do |row| 
    puts row.inspect 
    end 
end 

,但在執行時,它拋出:

/Users/foo/.rvm/rubies/ruby-2.1.0/lib/ruby/2.1.0/csv.rb:1256:in `initialize': no implicit conversion of Bzip2::Reader into String (TypeError) 
from /Users/foo/.rvm/rubies/ruby-2.1.0/lib/ruby/2.1.0/csv.rb:1256:in `open' 
from /Users/foo/.rvm/rubies/ruby-2.1.0/lib/ruby/2.1.0/csv.rb:1256:in `open' 
from /Users/foo/.rvm/rubies/ruby-2.1.0/lib/ruby/2.1.0/csv.rb:1121:in `foreach' 
from worm_pathfinder_solver.rb:79:in `block in <main>' 
from worm_pathfinder_solver.rb:77:in `open' 
from worm_pathfinder_solver.rb:77:in `<main>' 

問題

哪裏不對? 我該怎麼辦?

回答

1

基於你可能需要發送read方法bzip2的對象上的簡短文檔(未測試):

Bzip2::Reader.open(filename) do |bzip2| 
    CSV.foreach(bzip2.read) do |row| 
    #    ^^^^ 
    puts row.inspect 
    end 
end 
+1

我認爲這是錯誤的 - 它應該是{{CSV.parse(bzip2.read)do ...}}。當然,這一次將整個文件讀入所有文件,這可能代價高昂 - 我們通常會壓縮原因 - 而其他答案似乎允許逐行處理,而無需將文件讀入內存。 –

1

我的猜測是CSV試圖將Bzip2::Reader轉換爲字符串,但不知道如何並簡單地拋出異常。您可以手動將數據讀入一個字符串,然後將THAT傳遞給CSV

雖然它很奇怪,因爲它可以處理Bzip2 :: Writer就好。

4

CSV.foreach假設你傳遞一個文件路徑打開。如果你想傳遞一個流到CSV,你需要更加明確,並使用CSV.new。此代碼將處理gzip文件:

Zlib::GzipReader.open(filename) do |gzip| 
    csv = CSV.new(gzip) 
    csv.each do |row| 
    puts row.inspect 
    end 
end