Question

Je veux décompressez un grand nombre de fichiers zip. Y at-il un module ou d'un script qui vérifie le format du fichier zip est et décompresse? Cela devrait fonctionner sous Linux, je ne me soucie pas d'autres systèmes d'exploitation.

Était-ce utile?

La solution

Pour extraire des fichiers à partir d'un fichier tar.gz vous pouvez utiliser les méthodes suivantes de paquets 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 :: TarReader :: Points d'entrée dans un fichier ou un répertoire dans le fichier tar.gz.

un code similaire peut être utilisé (remplacer Reader avec Writer) pour écrire des fichiers dans un fichier tar.gz.

Autres conseils

Le plus simple est d'utiliser probablement Zlib

Zlib est une bibliothèque Ruby. Ce qui suit est un programme simple pour récupérer un fichier à partir d'une URL Zippé particulier, décompressez et coller 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 cette aide.

Bien réponse Florian est juste, il ne prend pas en compte tar LongLinks (essayez extraire jdk-7u40-linux-i586.tar.gz d'Oracle: P). Le code suivant devrait être en mesure de le faire:

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

Draco, thx pour vous extrait. Certains répertoires comme RAT encodent chemins se terminant par « / » - voir ce Wiki. goudron Examlple est serveur Oracle JRE 7u80 pour Windows . Cela fonctionne 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top