2009-06-08 3 views
7

대상 디렉토리에 이미 존재하거나 존재하지 않을 수도있는 파일이 여러 개있는 파일을 압축 해제하려고합니다. 파일이 이미 존재하는 경우 예외를 throw하는 것이 기본 동작 인 것 같습니다.Rubyzip lib를 사용하여 기존 파일을 덮어 쓰는 방법

디렉토리에 압축을 풀고 기존 파일을 덮어 쓰려면 어떻게합니까?

begin 
    Zip::ZipFile.open(source) do |zipfile| 
    dir = zipfile.dir 
    dir.entries('.').each do |entry| 
     zipfile.extract(entry, "#{target}/#{entry}") 
    end 
    end 
rescue Exception => e 
    log_error("Error unzipping file: #{local_zip} #{e.to_s}") 
end 

답변

12

그 추출물() 당신이 이미 존재하는 경우 파일을 통해 수행 할 수있는 작업을 결정 할 수있는 옵션 블록 (onExistsProc) 소요 표시 - 덮어 true를 반환을 , 예외를 발생시키는 경우는 false 당신은 단순히 기존의 모든 파일을 덮어 쓰기를 원한다면

, 당신이 할 수 있습니다 :

zipfile.extract(entry, "#{target}/#{entry}") { true } 

을 다르게 특정 항목을 처리 할 수있는 좀 더 복잡한 논리를 수행하려는 경우, 당신은 할 수 있습니다 :

zipfile.extract(entry, "#{target}/#{entry}") {|entry, path| some_logic(entry, path) } 

수정 : 고정 응답 - Ingmar Hamer가 지적한 것처럼 원래의 대답은 위 구문을 사용하여 예상 한 경우 매개 변수로 블록을 전달했습니다. 답 2

추출 명령이 잘못된 :

+0

이 답변은 실제로 게시 된 것처럼 작동하지 않습니다. 잉그마 하머 (Ingmar Hamer)가 게시 한 답변을 확인하고 그의 시정 내용을 알려주십시오. –

1

편집 :이 사전에 존재하는 경우 대상 파일을 제거하는 수정 된 코드

여기 내 코드입니다.

require 'rubygems' 
require 'fileutils' 
require 'zip/zip' 

def unzip_file(file, destination) 
    Zip::ZipFile.open(file) { |zip_file| 
    zip_file.each { |f| 
    f_path=File.join(destination, f.name) 
    if File.exist?(f_path) then 
     FileUtils.rm_rf f_path 
    end 
    FileUtils.mkdir_p(File.dirname(f_path)) 
    zip_file.extract(f, f_path) 
    } 
    } 
end 

unzip_file('/path/to/file.zip', '/unzip/target/dir') 

편집 : 대상 디렉토리가 사전에 존재하는 경우 수정 된 코드.

require 'rubygems' 
require 'fileutils' 
require 'zip/zip' 

def unzip_file(file, destination) 
    if File.exist?(destination) then 
    FileUtils.rm_rf destination 
    end 
    Zip::ZipFile.open(file) { |zip_file| 
    zip_file.each { |f| 
    f_path=File.join(destination, f.name) 
    FileUtils.mkdir_p(File.dirname(f_path)) 
    zip_file.extract(f, f_path) 
    } 
    } 
end 

unzip_file('/path/to/file.zip', '/unzip/target/dir') 

여기 the original code from Mark Needham입니다 :

require 'rubygems' 
require 'fileutils' 
require 'zip/zip' 

def unzip_file(file, destination) 
    Zip::ZipFile.open(file) { |zip_file| 
    zip_file.each { |f| 
    f_path=File.join(destination, f.name) 
    FileUtils.mkdir_p(File.dirname(f_path)) 
    zip_file.extract(f, f_path) unless File.exist?(f_path) 
    } 
    } 
end 

unzip_file('/path/to/file.zip', '/unzip/target/dir') 
+0

답변 주셔서 감사합니다.하지만 기존 파일을 덮어 쓰지 않는 것 같습니다. 존재한다면 그냥 건너 뛸 것입니다. – digitalsanctum

+0

... 실제로 존재하는 파일은 건너 뜁니다. 게시하기 전에 특정 유즈 케이스를 테스트하지 않는 것은 얼마나 어리석은 짓인가. 내 사과. 이미 존재하는 경우 대상 디렉토리를 제거 할 것입니다 내 편집 버전을 참조하십시오. – bernie

+0

그리고 제 두 번째 해결책은 또한 차선책이었습니다. 전체 디렉토리를 삭제하는 것은 거의 권장되지 않습니다. 하지만 세 번째는 매력이라고 생각합니다. 새 파일을 작성하기 전에 파일을 삭제하려면 약간의 코드를 추가해야합니다. – bernie

14

그냥 다른 사람에게 문제를 저장 루비를 의미하는 것이 될 것으로 예상, 세 번째 (PROC) 매개 변수는 앰퍼샌드 wtih 지정

{} - 이 같은 메소드 호출 후 브래킷 :

zipfile.extract(entry, "#{target}/#{entry}"){ true } 

또는 (더 복잡한 로직을 필요로하는 경우)

zipfile.extract(entry, "#{target}/#{entry}") {|entry, path| some_logic(entry, path) } 

게시물 # 2에 주어진 예제를 사용하면 "유효하지 않은 인수 (3에 2)"오류가 발생합니다 ...

+0

고맙습니다. 나는 Ruby를 처음 사용하고 한 시간 동안이 벽에 맞서 머리를 때렸다. –

0

link here은 내가 작동을 확인한 좋은 예입니다. 그냥 'fileutils'를 추가해야합니다.

관련 문제