/ / Perl leyendo archivos zip con IO :: Uncompress :: AnyUncompress - perl, descomprimir

Perl lee archivos zip con IO :: Uncompress :: AnyUncompress - perl, descomprimir

Nos estamos moviendo de nuestro sistema de construcción actual(que es un desastre) a uno que usa Ant con Ivy. Estoy limpiando todos los archivos de compilación y encontrando las dependencias de los archivos jar. Pensé que podría ser más fácil si pudiera automatizarlo un poco, revisando los archivos jar en el proyecto, encontrando qué clases contienen y luego emparejando esas clases con los diversos import Declaraciones en el código de Java.

He usado Archive::Tar antes, pero Archive::Zip no es un módulo estándar de Perl. (Mi preocupación es que alguien va a probar mi guión, llámame en mitad de la noche y dime que no está funcionando).

Me di cuenta que IO::Uncompress::AnyUncompress is a standard module, so I thought I could tryIO :: Uncompress :: AnyUncompressor at leastIO :: Uncompress :: Unzip` que también es un módulo estándar.

Desafortunadamente, la documentación de estos módulos no proporciona ejemplos (según la documentación, los ejemplos son una que hacer)

Puedo abrir exitosamente mi tarro y crear un objeto:

 my $zip_obj = IO::Uncompress::AnyUncompress->new ( $zip_file );

Ahora, quiero ver los contenidos. Según la documentación:

getHeaderInfo

El uso es

$hdr  = $z->getHeaderInfo();
@hdrs = $z->getHeaderInfo();

Este método devuelve una referencia de hash (encontexto escalar) o una lista o referencias de hash (en contexto de matriz) que contienen información sobre cada uno de los campos de encabezado en la (s) corriente (s) de datos comprimidos.

Bien, esto no es un objeto como Archive::Tar o Archive::Zip devuelve, y no hay métodos o subrutinas mencionadas para analizar los datos. Yo usaré Data::Dumper y ver qué claves hash están contenidas en la referencia.

Aquí hay un programa de prueba simple:

#! /usr/bin/env perl
use 5.12.0;
use warnings;

use IO::Uncompress::AnyUncompress;
use Data::Dumper;

my $obj = IO::Uncompress::AnyUncompress->new("testng.jar")

or die qq(You"re an utter failure);

say qq(Dump of $obj = ) . Dumper $obj;

my @header2 = $obj->getHeaderInfo;
say qq(Dump of $header = ) . Dumper $headers->[0];

Y aquí están mis resultados:

Dump of $obj = $VAR1 = bless( *Symbol::GEN0, "IO::Uncompress::Unzip" );

Dump of $header = $VAR1 = {
"UncompressedLength" => 0,
"Zip64" => 0,
"MethodName" => "Stored",
"Stream" => 0,
"Time" => 1181224440,
"MethodID" => 0,
"CRC32" => 0,
"HeaderLength" => 43,
"ExtraFieldRaw" => "¦-  ",
"ExtraField" => [
[
"¦-",
""
]
],
"FingerprintLength" => 4,
"Type" => "zip",
"TrailerLength" => 0,
"CompressedLength" => 0,
"Name" => "META-INF/",
"Header" => "PK
+N¦6                 META-INF/¦-  "
};

Algo de eso parece algo útil. Sin embargo, todas mis entradas devuelven `" Nombre "=>" META-INF / ``, por lo que no parece un nombre de archivo.

¿Es posible usar IO::Uncompress::AnyUncompress (o incluso IO::Uncompress:Unzip) para leer el archivo y ver qué archivos están en su contenido. Y, si es así, ¿cómo puedo analizar ese encabezado?

De lo contrario, tendré que ir con Archive::Zip y que la gente sepa que tienen que descargarlo e instalarlo desde CPAN en sus sistemas.

Respuestas

3 para la respuesta № 1

Los archivos en el archivo están comprimidos en diferentes flujos de datos, por lo que debe recorrerlos para obtener los archivos individuales.

use strict;
use warnings;
use IO::Uncompress::Unzip qw(unzip $UnzipError);

my $zipfile = "zipfile.zip";
my $u = new IO::Uncompress::Unzip $zipfile
or die "Cannot open $zipfile: $UnzipError";

die "Zipfile has no members"
if ! defined $u->getHeaderInfo;

for (my $status = 1; $status > 0; $status = $u->nextStream) {
my $name = $u->getHeaderInfo->{Name};
warn "Processing member $namen" ;

if ($name =~ //$/) {
mkdir $name;
}
else {
unzip $zipfile => $name, Name => $name
or die "unzip failed: $UnzipErrorn";
}
}