1

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

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 --

问题是如何在不实际提取成员文件大小的情况下检索它们。

4

2 回答 2

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";
}
于 2013-02-18T21:44:20.557 回答
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

在我的测试中产生了(抑制了一些输出):

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
...
于 2013-02-18T18:13:28.693 回答