2013-02-18 2 views
1

Я пытаюсь прочитать размер каждого члена-члена из zip без фактического извлечения. Я повторяю все имена членов, затем использую Archive::Zip::MemberRead, чтобы получить дескриптор файла для каждого члена, против которого я надеялся использовать метод stat для получения размера. Однако stat на дескрипторе файла из zip-файла возвращает пустой массив, поэтому я не могу получить размер моего файла. Вот мой код:Получение размера члена от zip с помощью архива :: Zip :: MemberRead

my $zip = Archive::Zip->new($zipFilePath); 

my @mbrs = $zip->memberNames(); 

foreach my $mbrName(@mbrs) 
{ 
    my $fh = Archive::Zip::MemberRead->new($zip, $mbrName); 

    my @fileStats = stat($fh); 
    my $size = $fileStats[7]; 

    print "\n".$mbrName." -- ".$size; 
} 

Однако выход я не отображает размер файла:

dir/fileName1.txt -- 
dir/fileName2.txt -- 

Вопрос заключается в том, как получить размеры файлов член фактически не извлекая их.

ответ

2

Почему бы просто не использовать сам модуль Archive::Zip? Это, кажется, работает для меня:

#!/usr/bin/perl 
use strict; 
use warnings; 
use Archive::Zip qw(:ERROR_CODES :CONSTANTS); 

my $filename = "somezipfile.zip"; 

# Read in the ZIP file  
my $zip = Archive::Zip->new(); 
unless ($zip->read($filename) == AZ_OK) { 
    die "Read error\n"; 
} 

# Loop through the members, printing their name, 
# compressed size, and uncompressed size. 
my @members = $zip->members(); 
foreach (@members) 
{ 
    print " - " . $_->fileName() . ": " . $_->compressedSize() . 
     " (" . $_->uncompressedSize() . ")\n"; 
} 
+0

Красивые !! Огромное спасибо. – amphibient

1

Вот только один способ, если у вас есть 7-zip установлены:

#!/usr/bin/env perl 

use warnings; 
use strict; 

## List files from zip file provided as first argument to the script, the format 
## is like: 
# Date  Time Attr   Size Compressed Name 
#------------------- ----- ------------ ------------ ------------------------ 
#2012-10-19 16:56:38 .....   139   112 1.txt 
#2012-10-19 16:56:56 .....   126   105 2.txt 
#2012-10-19 16:57:24 .....   71   53 3.txt 
#2012-10-03 14:39:54 .....   155   74 A.txt 
#2012-09-29 17:53:44 .....   139   70 AA.txt 
#2011-12-08 10:41:16 .....   30   30 AAAB.txt 
#2011-12-08 10:41:16 .....   18   18 AAAC.txt 
# ... 
for (map { chomp; $_ } qx/7z l $ARGV[0]/) { 

    # Omit headers and footers with this flip-flop. 
    if (my $l = (m/^(?:-+\s+){2,}/ ... m/^(?:-+\s+){2,}/)) { 

     ## Don't match flip-flop boundaries. 
     next if $l == 1 || $l =~ m/E0$/; 

     ## Extract file name and its size. 
     my @f = split ' '; 
     printf qq|%s -- %d bytes\n|, $f[5], $f[3]; 
    } 
} 

Я бегу это нравится:

perl script.pl files.zip 

Это yiedls в моем тесте (с некоторым выходом подавлено):

1.txt -- 139 bytes 
2.txt -- 126 bytes 
3.txt -- 71 bytes 
A.txt -- 155 bytes 
AA.txt -- 139 bytes 
AAAB.txt -- 30 bytes 
AAAC.txt -- 18 bytes 
B.txt -- 40 bytes 
BB.txt -- 131 bytes 
C.txt -- 4 bytes 
CC.txt -- 184 bytes 
File1.txt -- 177 bytes 
File2.txt -- 250 bytes 
aaa.txt -- 30 bytes 
... 
+0

Я надеялся сделать это без 7-zip. но спасибо – amphibient

Смежные вопросы