Techioz Blog

zipファイルの中身を解凍せずに別のzipファイルで読む方法

概要

多数の zip ファイルを含む zip ファイルがあります。内部 zip をファイルシステムに解凍せずに内容を確認したいと考えています。

Zip::File.foreach を使用して外側の zip ファイルの内容を反復処理すると、内容を検査したい zip ファイルを表す Zip::Entry が得られます。サブzipをファイルシステムに解凍せずにそれを行う方法がわかりません。

su-bzip で .extract(“some_destination.zip”) を呼び出して、それを通常のトップレベル zip のように扱うことができます。これは機能しますが、単体テストで内容を検証したいだけなので、ファイル システムに不必要に書き込みたくありません。

補足: 誰かが「なぜ」サブ zip を使用しているのかを尋ねたり、これに圧縮価値がないことを指摘したりする前に… Apple は、Apple ウォレットに複数のチケットを追加するために、ZIP の ZIP を作成することを望んでいるからです。同時に。

解決策

簡単な方法は、外側の zip エントリの内容をメモリ内で読み取り、Zip::File.open_buffer API を使用して新しい Zip インスタンスをインスタンス化することです。

次の例では、簡単にするために、外側の zip ファイルには、プレーンテキスト ファイルが含まれる内側の zip ファイルが含まれていると仮定します。

require 'zip'
require 'stringio'

outer_zip_file = Zip::File.open('outer.zip')

outer_entry = outer_zip_file.entries.first
outer_entry_data = outer_entry.get_input_stream.read

inner_zip = Zip::File.open_buffer(outer_entry_data)

inner_entry = inner_zip.entries.first
puts inner_entry.get_input_stream.read

同じタスクを実行するためにストリームを使用することもおそらく可能ですが、間違いを犯しやすくなり (つまり、デバッグ中に誤って複数回読み取ってしまう)、ファイルが十分に小さい場合 (そしてもちろん攻撃のリスクがない)、メモリ内でも許容されます。