Skip to content

Instantly share code, notes, and snippets.

@masukomi
Last active August 30, 2023 16:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save masukomi/9c820dccbb6d9535536ab9945153b48c to your computer and use it in GitHub Desktop.
Save masukomi/9c820dccbb6d9535536ab9945153b48c to your computer and use it in GitHub Desktop.
[ruby] how to recursively process a zip file containing zip files in memory
#!/usr/bin/env ruby
# Note this doesn't deal with directories in zip files.
# That's documented elsewhere. The recursive processing of
# zip files in zip files was the tricky bit.
require 'zip'
def recursive_zip_reader(input)
if input.is_a? String
zip_file = Zip::File.open(input)
recursive_zip_file_reader(zip_file)
elsif input.is_a? Zip::File
recursive_zip_file_reader(input)
elsif input.is_a? Zip::Entry
recursive_zip_entry_reader(input)
elsif input.is_a? File
recursive_zip_file_reader(Zip::File.open(input.path))
else
"unknown input type (#{input.class}): #{input}"
end
end
def recursive_zip_file_reader(zip_file)
file_names = []
zip_file.entries.each do | zip_entry |
# nobody wants macOS's bs finder metadata files
next if zip_entry.name.start_with?("__MACOSX")
file_names << recursive_zip_entry_reader(zip_entry)
end
file_names
end
def recursive_zip_entry_reader(zip_entry)
name = zip_entry.name
return name unless name.end_with?(".zip")
entry_contents = zip_entry.get_input_stream.read
nested_entry = Zip::File.open_buffer(entry_contents)
{name => recursive_zip_reader(nested_entry)}
end
puts recursive_zip_reader("multizip.zip").inspect
# output should look like this
# [
# {
# "subzip.zip": [
# "pass.json",
# "manifest.json",
# "signature"
# ]
# }
# ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment