(zip, décompressez le goudron, tag.gz) fichiers avec ruby
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.
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