使用Archive :: Zip :: MemberRead从zip获取成员大小

时间:2013-02-18 17:26:47

标签: perl zip

我试图从zip中读取每个成员文件大小而不实际提取。我遍历所有成员名称,然后使用Archive::Zip::MemberRead获取每个成员的文件句柄,我希望能够使用stat方法来获取大小。但是,zip文件元素的文件句柄上的stat返回一个空数组,因此无法获取文件大小。这是我的代码:

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 个答案:

答案 0 :(得分:4)

为什么不直接使用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";
}

答案 1 :(得分:2)

只有安装了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
...