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.

¿Fue útil?

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top