2010-02-24 2 views
7

나는 zip 출력에 디렉토리를 추가하기 위해 rubyzip을 얻는 데 어려움을 겪고 있습니다. (레일즈 컨트롤러에서 보낼 수 있도록 출력 스트림을 원합니다.)rubyzip을 사용하여 파일과 중첩 된 디렉토리를 zipoutputstream에 추가하십시오.

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

나는 다음과 같은 오류가 추가 할 파일 목록에서 디렉토리를 포함하도록 수정 :

어떤 도움도 대단히 감사하겠습니다 내 코드는이 예제를 다음과 같습니다. http://zipruby.rubyforge.org/ :

UPDATE

솔루션의 숫자를 시도 후 나는 깨끗한 API를 좋은 예로이있는 zipruby 최상의 성공을 거두었 다.

+0

zipruby를 찾는 훌륭한 직장은 내 하루를 저장했습니다! –

답변

5

OOOOOuuuhh ... 당신은 분명히 ZIPPY를 원합니다. Rubyzip에서 많은 복잡성을 추상화하는 Rails 플러그인이며 디렉토리 (내가 기억하는 것)를 포함하여 여러분이 말하는 것을 만들 수 있습니다. 여기

당신은 갈 :

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를 사용하는 목적은 루비 지퍼를 사용하는 것이 훨씬 쉽도록 만드는 것입니다. 씨야

다음은 디렉토리와 디렉토리를 만드는 방법입니다 ... 두 번째 (또는 첫 번째) 볼이 걸릴 수도 있습니다 :

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 스트림을 만들고 디렉토리 디렉토리를 추가하는 방법은 무엇입니까? 또한 맞춤 mime 형식이 아닌 sendfile을 사용해야합니다. 감사. – fturtle

+0

가 답을 수정했습니다. – btelles

+0

죄송합니다.하지만이 보석은 상당히 열심히 일합니다. 내가 원하는 방식으로 새로 생성 된 zip을 스트리밍 할 수있는 몇 가지 다른 방법이 있습니다. – fturtle

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

3

기운찬이 작동합니다. 본질적으로 아무 문서도 없기 때문에 여기에 내가 Rakefile에서 Zippy로 디렉토리를 반복적으로 복사하기 위해 생각해 낸 것이 있습니다.

C:\> cd my 
C:\my> rake myzip 
:이처럼 사용할 수있는 Rakefile

이제
#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 

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

을 그리고 이것은이다 :이 Rakefile은 내 Gemfile에 보석 요구 사항을 넣어 있도록 레일 환경에서 사용되는

이고 선택한 파일 및 디렉토리의 사본이있는 'my'라는 내부 디렉토리가 포함 된 my.zip을 생성합니다.

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')zos.put_next_entry('some-funny-name.jpg')을 변경, 결과 ZipFile에이 파일을 포함 myfolder라는 중첩 된 폴더를했다.

+1

당신의 방법은 훌륭하게 작동했습니다, 감사합니다! 나는 거의''지퍼비 ''로 바꿨지 만 더 이상 유지되지 않는 것 같습니다. – rkallensee

관련 문제