1

実際に解凍せずに、各メンバーのファイル サイズを zip から読み取ろうとしています。すべてのメンバー名を反復処理し、各メンバーのファイル ハンドルを取得するために使用します。これに対して、メソッドを使用してサイズを取得Archive::Zip::MemberReadできるようにしたいと考えていました。statただし、statzipファイル要素からのファイルハンドルでは空の配列が返されるため、ファイルサイズを取得できません。これが私のコードです:

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がインストールされている場合の 1 つの方法です。

#!/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 に答える