web-dev-qa-db-fra.com

Dossiers Unzip (zip, tar, tag.gz) avec ruby=

Je veux décompresser beaucoup de fichiers zip. Existe-t-il un module ou un script qui vérifie quel format le fichier zip est et le décompresse? Cela devrait fonctionner sur Linux, je me fiche de l'autre OSS.

31
gustavgans

Pour extraire des fichiers à partir d'un fichier .tar.gz, vous pouvez utiliser les méthodes suivantes à partir des packages distribués avec 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

Chaque entrée de type - GEM :: paquet :: TARARREADER :: Entry pointe vers un fichier ou un répertoire dans le fichier .TAR.GZ.

Le code similaire peut être utilisé (remplacer le lecteur avec écrivain) pour écrire des fichiers sur un fichier .TAR.GZ.

31
Florian Feldhaus

Le moyen le plus simple est d'utiliser probablement zlib

Zlib est un Ruby Library. Ce qui suit est un programme simple pour saisir un fichier zippé à partir d'une URL particulière, décompressez-la et collez son contenu à l'écran.

require 'zlib' 
require 'open-uri'

uri = "www.somedomain.com/filename.gz"
source = open(uri)
gz = Zlib::GzipReader.new(source) 
result = gz.read
puts result

J'espère que ça aide.

29
user244854

Bien que Réponse de Florian a raison, il ne prend pas en compte Tar Longlinks (essayez d'extraire JDK-7U40-Linux-i586.tar.gz de Oracle: p). Le code suivant devrait pouvoir faire cela:

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
12
Draco Ater

Draco, Thx pour vous extrait . Certaines guichets encodent des annuaires en tant que chemins se terminant par '/' - voir - this wiki. Examplement Tar est Oracle Server JRE 7U80 pour Windows . Cela fonctionnera pour eux:

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
2
TomCZ