распаковать (zip, tar, tag.ГЗ) файлы с Рубином
Я хочу распаковать много zip-файлов. Есть ли модуль или скрипт, который проверяет, в каком формате находится zip-файл, и распаковывает его? Это должно работать на Linux, я не забочусь о других ОС.
4 ответа:
Для извлечения файлов из a .смола.файл gz вы можете использовать следующие методы из пакетов, распространяемых с Ruby:
require 'rubygems/package' require 'zlib' tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open('Path/To/myfile.tar.gz')) tar_extract.rewind # The extract has to be rewinded after every iteration tar_extract.each do |entry| puts entry.full_name puts entry.directory? puts entry.file? # puts entry.read end tar_extract.close
Каждая запись типа Gem:: Package:: TarReader:: Entry указывает на файл или каталог внутри .смола.файл gz.
Подобный код может быть использован (заменить читателя с писателем), чтобы писать файлы .смола.файл gz.
Самый простой способ, вероятно, использовать Zlib
Zlib-это библиотека Ruby. Далее следует простая программа, позволяющая захватить сжатый файл из определенного URL, распаковать его и вставить его содержимое на экран.
require 'zlib' require 'open-uri' uri = "www.somedomain.com/filename.gz" source = open(uri) gz = Zlib::GzipReader.new(source) result = gz.read puts result
Надеюсь, это поможет.
Хотя Флориана ответа прав, он не учел дегтя LongLinks (добывайте в JDK-7u40-Линукс-для i586.смола.gz от oracle: P). Следующий код должен быть в состоянии сделать это:
require 'rubygems/package' require 'zlib' TAR_LONGLINK = '././@LongLink' tar_gz_archive = '/path/to/archive.tar.gz' destination = '/where/extract/to' Gem::Package::TarReader.new( Zlib::GzipReader.open tar_gz_archive ) do |tar| dest = nil tar.each do |entry| if entry.full_name == TAR_LONGLINK dest = File.join destination, entry.read.strip next end dest ||= File.join destination, entry.full_name if entry.directory? File.delete dest if File.file? dest FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false elsif entry.file? FileUtils.rm_rf dest if File.directory? dest File.open dest, "wb" do |f| f.print entry.read end FileUtils.chmod entry.header.mode, dest, :verbose => false elsif entry.header.typeflag == '2' #Symlink! File.symlink entry.header.linkname, dest end dest = nil end end
Драко, thx для тебя фрагмент . Некоторые TARs кодируют каталоги как пути, заканчивающиеся на ' / ' - см. this Wiki. Examlple tar - этоOracle Server JRE 7u80 для Windows . Это будет работать для них:
require 'fileutils' require 'rubygems/package' require 'zlib' TAR_LONGLINK = '././@LongLink' Gem::Package::TarReader.new( Zlib::GzipReader.open tar_gz_archive ) do |tar| dest = nil tar.each do |entry| if entry.full_name == TAR_LONGLINK dest = File.join destination, entry.read.strip next end dest ||= File.join destination, entry.full_name if entry.directory? || (entry.header.typeflag == '' && entry.full_name.end_with?('/')) File.delete dest if File.file? dest FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false elsif entry.file? || (entry.header.typeflag == '' && !entry.full_name.end_with?('/')) FileUtils.rm_rf dest if File.directory? dest File.open dest, "wb" do |f| f.print entry.read end FileUtils.chmod entry.header.mode, dest, :verbose => false elsif entry.header.typeflag == '2' #Symlink! File.symlink entry.header.linkname, dest else puts "Unkown tar entry: #{entry.full_name} type: #{entry.header.typeflag}." end dest = nil end end end