descomprimir (ZIP, TAR, tag.gz) archivos con el rubí
Pregunta
Quiero descomprimir una gran cantidad de archivos zip. ¿Hay un módulo o un script que comprueba el formato del archivo zip y descomprime es él? Esto debería funcionar en Linux, no me importa acerca de otros sistemas operativos.
Solución
Para extraer archivos de un archivo .tar.gz se pueden utilizar los siguientes métodos de paquetes distribuidos con 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
Cada entrada del tipo Gem :: paquete :: TarReader :: puntos de entrada a un archivo o directorio en el archivo .tar.gz.
código similar se puede utilizar (sustituir lector con el escritor) para escribir archivos en un archivo .tar.gz.
Otros consejos
La forma más sencilla es utilizar probablemente Zlib
Zlib es una biblioteca de Ruby. Lo que sigue es un programa sencillo para tomar un archivo comprimido desde una URL concreta, descomprimirlo, y pegar su contenido a la pantalla.
require 'zlib'
require 'open-uri'
uri = "www.somedomain.com/filename.gz"
source = open(uri)
gz = Zlib::GzipReader.new(source)
result = gz.read
puts result
Espero que esto ayude.
de Florian respuesta es correcto, que no toma en cuenta tar LongLinks (Intenta extraer jdk-7u40-linux-i586.tar.gz de Oracle: P). El siguiente código debe ser capaz de hacer esto:
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 para usted fragmento . Algunos TAR codifican directorios como caminos que terminan con '/' - ver este Wiki. tar Examlple es 7u80 servidor Oracle JRE para Windows . Esto funcionará para ellos:
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