2010-02-24 40 views
7

我正在努力獲得rubyzip將目錄追加到zipoutputstream。 (我想輸出流,所以我可以從軌道控制器發送它)。我的代碼如下例所示:使用rubyzip將文件和嵌套目錄添加到zipoutputstream

http://info.michael-simons.eu/2008/01/21/using-rubyzip-to-create-zip-files-on-the-fly/

當修改爲包括在文件列表目錄添加我得到以下錯誤:

任何幫助將不勝感激。

UPDATE

嘗試了一些解決方案後,我曾與zipruby其中有一個乾淨的API和很好的例子最成功的:http://zipruby.rubyforge.org/

+0

找到zipruby的好工作,拯救了我的一天! – 2011-05-20 09:23:05

回答

5

OOOOOuuuhh ...你肯定想要ZIPPY。這是一個Rails插件,可以抽象出rubyzip中的很多複雜性,並且可以創建你正在談論的內容,包括目錄(從我記得的內容)。

在這裏你去:

http://github.com/toretore/zippy

而且從比比網站直接:

Example controller: 
def show 
    @gallery = Gallery.find(params[:id]) 
    respond_to do |format| 
    format.html 
    format.zip 
    end 
end 

Example view: 
zip['description.txt'] = @gallery.description 
@gallery.photos.each do |photo| 
    zip["photo_#{photo.id}.png"] = File.open(photo.url) 
end 

編輯

嗯...全:每用戶評論修憲使用Zippy的目的是使它更容易使用ruby zip。 雅可能要採取第二(或第一)看...

下面是如何使一個目錄,目錄:

some_var = Zippy.open('awsum.zip') do |zip| 
    %w{dir_a dir_b dir_c diri}.each do |dir| 
    zip["bin/#{dir}/"] 
    end 
end 

... 

send_file some_var, :file_name => ... 
+0

感謝這看起來不錯,但文檔有點害羞,我沒有時間鑽研源代碼。所以,例如,我將如何創建一個zip流並添加一個目錄目錄?另外,我需要使用sendfile而不是自定義MIME類型。謝謝。如果您有興趣, – fturtle 2010-02-24 16:38:19

+0

修復了答案。 – btelles 2010-02-24 23:59:21

+0

對不起,但我發現這個寶石是相當艱苦的工作。還有一些其他的我會嘗試以我想要的方式流傳一個新創建的zip文件。 – fturtle 2010-02-26 13:47:07

9
Zip::ZipFile.open(path, Zip::ZipFile::CREATE) do |zip| 
    songs.each do |song| 
    zip.add "record/#{song.title.parameterize}.mp3", song.file.to_file.path 
    end 
end 
+0

這很簡單,它的工作原理 – benjineer 2014-05-03 07:39:25

3

比比會爲這方面的工作。可能有更酷的方法來做到這一點,但由於基本上沒有文檔,這裏是我想出了用Rappyfile遞歸複製Zippy目錄的方法。這Rake文件是在Rails環境中使用,所以我把寶石的要求在我的Gemfile:

#Gemfile 
source 'http://rubygems.org' 
gem 'rails' 
gem 'zippy' 

這是Rake文件

#Rakefile 
def add_file(zippyfile, dst_dir, f) 
    zippyfile["#{dst_dir}/#{f}"] = File.open(f) 
end 

def add_dir(zippyfile, dst_dir, d) 
    glob = "#{d}/**/*" 
    FileList.new(glob).each { |f| 
    if (File.file?(f)) 
     add_file zippyfile, dst_dir, f 
    end 
    } 
end 

task :myzip do 
    Zippy.create 'my.zip' do |z| 
    add_dir z, 'my', 'app' 
    add_dir z, 'my', 'config' 
    #... 
    add_file z, 'my', 'config.ru' 
    add_file z, 'my', 'Gemfile' 
    #... 
    end 
end 

現在我可以這樣使用它:

C:\> cd my 
C:\my> rake myzip 

,它將生成my.zip,其中包含一個名爲'my'的內部目錄以及所選文件和目錄的副本。

2

我能夠使用original article中使用的相同ZipOutputStream的目錄工作。

我只需要調用zos.put_next_entry時添加目錄。

例如:

require 'zip/zip' 
require 'zip/zipfilesystem' 

t = Tempfile.new("some-weird-temp-file-basename-#{request.remote_ip}") 
# Give the path of the temp file to the zip outputstream, it won't try to open it as an archive. 
Zip::ZipOutputStream.open(t.path) do |zos| 
    some_file_list.each do |file| 
    # Create a new entry with some arbitrary name 
    zos.put_next_entry("myfolder/some-funny-name.jpg") # Added myfolder/ 
    # Add the contents of the file, don't read the stuff linewise if its binary, instead use direct IO 
    zos.print IO.read(file.path) 
    end 
end 
# End of the block automatically closes the file. 
# Send it using the right mime type, with a download window and some nice file name. 
send_file t.path, :type => 'application/zip', :disposition => 'attachment', :filename => "some-brilliant-file-name.zip" 
# The temp file will be deleted some time... 
t.close 

我只是改變​​到zos.put_next_entry('myfolder/some-funny-name.jpg'),並將得到的zip文件必須包含文件名爲myfolder嵌套文件夾。

+1

你的方法工作得很好,謝謝!我幾乎切換到'''zipruby''',但它似乎不再被維護。 – rkallensee 2014-05-13 13:58:51