2010-07-02 159 views
7

我有一個包含XML文檔的.gz文件。有誰知道如何正確使用Zlib?到目前爲止,我有以下代碼:Ruby中的Zlib解壓縮.gz

require 'zlib' 
Zlib::GzipReader.open('PRIDE_Exp_Complete_Ac_1015.xml.gz') { |gz| 
    g = File.new("PRIDE_Exp_Complete_Ac_1015.xml", "w") 
     g.write(gz) 
     g.close() 
} 

但是,這會創建一個空白的.xml文檔。有誰知道我可以如何正確地做到這一點?

回答

22

Zlib::GzipReader像大多數類似於Ruby的IO類。你有一個open調用,當你傳遞一個塊時,塊將會收到類似於IO的對象。想想這是在塊的持續時間內使用文件或資源進行某些操作的便捷方式。

但這意味着在您的示例中,gz是一個類似於IO的對象,並且實際上並不像您期望的那樣是gzip文件的內容。你仍然需要read來達到目的。然後,簡單的解決辦法是:

g.write(gz.read) 

注意,這將讀取未壓縮的gzip的全部內容到內存中。

如果您真的在做的是從一個文件複製到另一個文件,您可以使用更高效的方法IO.copy_stream。然後,您的例子可能是這樣的:

Zlib::GzipReader.open('PRIDE_Exp_Complete_Ac_1015.xml.gz') do | input_stream | 
    File.open("PRIDE_Exp_Complete_Ac_1015.xml", "w") do |output_stream| 
    IO.copy_stream(input_stream, output_stream) 
    end 
end 

在幕後,這將嘗試使用可用的系統調用sendfile在Linux上的一些具體情況。否則,它將一次執行快速C代碼16KB塊的複製。這是我從Ruby 1.9.1源代碼中學到的。

2

這裏是一個紅寶石單行(CD的.git /第一和識別路徑的任何對象):

ruby -rzlib -e 'print Zlib::Inflate.new.inflate(STDIN.read)' < ./74/c757240ec596063af8cd273ebd9f67073e1208