2009-05-13 6 views

Répondre

27

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::Package::TarReader::Entry pointe vers un fichier ou un répertoire dans le .tar.gz fichier.

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

27

La façon la 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 compressé d'une URL particulière, le décompresser 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 cela aide.

+0

Mavryx: Quand je suis en train de votre extrait Je reçois l'erreur suivante: unzip.rb: 5: Variable locale non définie ou méthode 'uri » pour # (NameError) – maetthew

+0

@maetthew vérifier la ligne 4 et assurez-vous que vous utilisez la même variable (uri ici) dans les deux lignes – BurmajaM

10

Bien que Florian's answer ait raison, il ne prend pas en compte tar LongLinks (Essayez d'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 
+0

est ': verbose = > false' nécessaire? –

+0

Non, je ne voulais rien imprimer dans mon cas d'utilisation. –

1

Draco, thx pour vous snippet. Certains TARs codent les répertoires comme des chemins se terminant par '/' - voir this Wiki. Le tar examiné est Oracle Server JRE 7u80 for 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 
Questions connexes