Rubyzip lib を使用して既存のファイルを上書きする方法

StackOverflow https://stackoverflow.com/questions/966054

  •  12-09-2019
  •  | 
  •  

質問

ターゲット ディレクトリに存在するか存在しない可能性のある複数のファイルを含むファイルを解凍しようとしています。ファイルがすでに存在する場合、デフォルトの動作では例外がスローされるようです。

ディレクトリに解凍し、既存のファイルを単純に上書きするにはどうすればよいですか?

私のコードは次のとおりです。

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
役に立ちましたか?

解決

extract() は、ファイルがすでに存在する場合にファイルをどうするかを決定できるオプションのブロック (onExistsProc) を取るようです。上書きする場合は true を返し、例外を発生させる場合は false を返します。

既存のファイルをすべて上書きしたい場合は、次のようにすることができます。

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

特定のエントリを別の方法で処理するために、より複雑なロジックを実行したい場合は、次のようにすることができます。

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

編集: 修正された答え - Ingmar Hamer によって指摘されたように、私の元の答えは、上記の構文を使用すると予期される場合にブロックをパラメーターとして渡しました。

他のヒント

ただ、他の人に迷惑を保存します:

答え2で抽出コマンドが間違っています:

第三(PROC)パラメータは、ルビーが、このようなメソッド呼び出しの後に{} -Bracketsであることを期待を意味し、アンパサンドwtih指定されている

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

または(あなたがより複雑なロジックが必要な場合)

zipfile.extract(entry, "#{target}/#{entry}") {|entry, path| some_logic(entry, path) }
あなたはポスト#2で与えられた例を使用する場合は、

あなたは「無効な引数(2 3)」エラー...

得られます

編集:それは事前に存在する場合は、対象ファイルを削除するには、コードを修正

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')

ここで元のコードです

:マーク・ニーダムするから
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')
ここで

このリンクは、私が作品を確認した良い例を提供します。ただ、必要「のfileutils」を持っている必要があり、それに追加します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top