2011-05-16 6 views
4

rubyzip을 사용하여 일반 zip 파일의 내용을 검색하는 방법을 알고 있습니다. 하지만 문제가 zip 폴더의 내용을 압축 해제하고 나는 너희들이 나를 도와 줄 수 있기를 바랍니다.rubyzip으로 압축 된 폴더의 압축을 해제하는 방법

Zip::ZipFile::open(@file_location) do |zip| 
zip.each do |entry| 
    next if entry.name =~ /__MACOSX/ or entry.name =~ /\.DS_Store/ or !entry.file? 
    logger.debug "#{entry.name}" 
    @data = File.new("#{Rails.root.to_s}/tmp/#{entry.name}") 
end 
end 

entry.name 나에게 압축 파일 안에있는 파일의 이름을 제공합니다

내가 압축을 해제하는 데 사용하는 코드입니다. 이것은 정상적인 zipfile과 완벽하게 작동합니다. 그러나 폴더에서 zip 파일을 만들면 항목 이름은 test-folder/test.pdf와 같습니다. 그런 다음 파일을 만들려고하면 파일을 찾을 수 없다는 메시지가 나타납니다. 이는 아마도 zip 내부의 "테스트"폴더 안에 있기 때문일 수 있습니다.

항목이 폴더인지 확인하면 폴더를 찾을 수 없습니다. 그래서 솔루션을 항목으로 스트림으로 읽은 다음 파일로 저장하는 것으로 생각했습니다. 엔트리 스트림을 얻는 것은 쉽지만 어떻게 파일로 저장합니까? 이것은 내가 지금까지 얻은 것이다.

Zip::ZipFile::open(@file_location) do |zip| 
zip.each do |entry| 
    next if entry.name =~ /__MACOSX/ or entry.name =~ /\.DS_Store/ or !entry.file? 
    logger.debug "#{entry.name}" 
    @data = entry.get_input_stream.read 
    # How do i create a file from a stream? 
end 
end 

기본적으로 내 질문은 : 스트림에서 파일을 어떻게 만듭니 까? 아니면 이것보다 쉽게 ​​접근 할 수 있습니까?

=== 편집 === 파일을 저장하기 위해 클립을 사용합니다.

답변

0

여러분의 문제는 스트림에서 파일을 작성해야하는지 아닌지 아닌지 생각합니다. 기본적으로 File.new으로 전화하면 will create a new IO-Stream (FileIO의 하위 클래스입니다.) 따라서 zip 파일의 스트림으로 수행하려는 작업은 일반 파일에서도 작동해야합니다. 당신은 내가 다음 파일을 만들려고 할 때

, 그것은 파일이

내가 무슨 일하는 생각

를 찾을 수 없습니다 알려줍니다 말

그 파일의 부모 디렉토리 당신은 창조하고 싶지 않다 (귀하의 경우에는 test-folder). 무엇을하고 싶은지는 다음과 같습니다 (테스트되지 않음).

Zip::ZipFile::open(@file_location) do |zip| 
zip.each do |entry| 
    next if entry.name =~ /__MACOSX/ or entry.name =~ /\.DS_Store/ or !entry.file? 
    logger.debug "#{entry.name}" 
    FileUtils::mkdir_p(File.dirname(entry.name)) # might want to check if it already exists  
    @data = File.new("#{Rails.root.to_s}/tmp/#{entry.name}") 
end 
end 
+0

코드를 시도했지만 프로젝트의 루트에 항목의 상위 폴더 만 만듭니다. 나는 여전히 자기 입장에 접근 할 수 없다. 사실 Errno :: ENOENT입니다. 나는 이것을 언급해야한다고 생각했습니다. thx tho – grub4r

0

스트림을 사용하고 StringIO를 작성하여 해결했습니다. 여기에 내가 jhwist의 기반으로 단순한 접근 방식은 확인했다 발견

Zip::ZipFile::open(@file_location) do |zip| 
zip.each do |entry| 
    next if entry.name =~ /__MACOSX/ or entry.name =~ /\.DS_Store/ or !entry.file? 

    begin 
    # the normal unzip-code 
    rescue Errno::ENOENT 
    # when the entry can not be found 
    @data = entry.get_input_stream.read 
    @file = StringIO.new(@data) 
    @file.class.class_eval { attr_accessor :original_filename, :content_type } 
    @file.original_filename = entry.name 
    @file.content_type = MIME::Types.type_for(entry.name) 

    # save it/whatever 
    end 
end 
end 
+0

첫 번째 줄은 다음과 같아야합니다. 'Zip :: ZipFile.open (@file_location) do | zip | ' – lightyrs

2

코드입니다 :

Zip::File.open(@file_location) do |zipfile| 
    zipfile.each do |entry| 
    # The 'next if...' code can go here, though I didn't use it 
    unless File.exist?(entry.name) 
     FileUtils::mkdir_p(File.dirname(entry.name)) 
     zipfile.extract(entry, entry.name) 
    end 
    end 
end 

을 조건부 분명히 선택 사항입니다,하지만 그것을 덮어 쓰기를 시도하는 경우없이 코드에서 오류가 발생합니다 기존 파일.

+0

이 접근법은 파일의 사용 권한을 보존하지 않습니다. 어떻게 압축을 푼 후에 사용 권한을 보존 할 수 있습니까? – itsh

관련 문제