解压缩失败目录下的所有文件—IO::Uncompress Perl



我试图使用IO::Compress解压缩目录中的所有文件,但我的脚本失败,没有错误细节。我使用IO::Uncompress::Unzip作为参考,它看起来很简单,但它只是死于:

<>以前root@test:/home/user/unzip.pl #它的存在。之前解压失败:
my $outputdir = "/tmp";
if ( <$outputdir/*.zip> ){
    print "Its there.n";
    unzip '<$outputdir/*.zip>' => '<$outputdir/#1>'
    or die "unzip failed: $UnzipErrorn";
}

我做错了什么?

我花了一些时间才弄清楚代码和语法。基本上,语法是:

  1. 打开压缩文件
  2. 读取下一个文件流(nextStream)时。
    1. 查找正在读取的文件流的名称
    2. 创建一个新文件写入(使用openFile::IO->new)
    3. 当文件流中有数据时(read)
      1. 写入新文件的缓冲区
    4. 关闭你创建的文件。
  3. 关闭压缩文件

的技巧是,如果读取有问题,两个while语句将返回一个小于0的状态(特别是-1)。它们在完成时返回零状态。因此,在while语句之后,您必须检查状态。

这是我使用的代码。注意,我没有导入$UnzipError,而是使用了变量的全名,包括它的包名。

#
# Unzip Artifact
#
my $zip_fh = IO::Uncompress::Unzip->new( $old_zip_file )
    or die qq(Cannot open zip "$old_zip_file" for reading.);
#
# Go through each element in Zip file
#
while ( my $status = $zip_fh->nextStream ) {
    if ( $status < 0 ) {
        die qq(Error in Zip: $IO::Uncompress::Unzip::UnzipError.);
    }
    #
    # Get name of the file you're unzipping in the zip
    #
    my $element_name = $zip_fh->getHeaderInfo->{Name};
    next if $element_name =~ m{/$};      # Skip Directories
    my $element_dir = dirname $element_name;
    my $full_element_dir = File::Spec->join( $unzip_directory, $element_dir );
    #
    # Create the directory for the file if it doesn't exist
    #
    my $full_element_name = File::Spec->join( $unzip_directory, $element_name );
    if ( not -d $full_element_dir ) {
        make_path $full_element_dir
            or die qq(Can't make directory "$full_element_dir".);
    }
    my $unzipped_fh = IO::File->new( $full_element_name, "w" )
        or die qq(Can't open file "$full_element_name" for writing: $!);
    #
    # Now repeatably read the file until you've written everything
    #
    my $buffer;
    while ( my $status = $zip_fh->read( $buffer ) ) {
        if ( $status < 0 ) {
            die qq(Error in Zip: $IO::Uncompress::Unzip::UnzipError.);
        }
        $unzipped_fh->write( $buffer );
    }
    $unzipped_fh->close;
}
$zip_fh->close;

你可以试试

use strict ;
use warnings ;
use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
for my $input ( glob "/tmp/*.zip" )
{
    my $output = $input;
    $output =~ s/.zip// ;
    unzip $input => $output or die "Error compressing '$input': $UnzipErrorn";
} 

我相信David W. 82.2k25154274(见下文)建议的修复有一个小错误。很好的例子,我复制了它,但它总是忽略一个文件!修复方法是初始化$status为1,并且只在循环结束时调用next。

修复:

#
# Unzip Artifact
#
my $zip_fh = IO::Uncompress::Unzip->new( $old_zip_file )
    or die qq(Cannot open zip "$old_zip_file" for reading.);
#
# Go through each element in Zip file
#
my $status = 1;
while ( $status ) {
    if ( $status < 0 ) {
        die qq(Error in Zip: $IO::Uncompress::Unzip::UnzipError.);
    }
    #
    # Get name of the file you're unzipping in the zip
    #
    my $element_name = $zip_fh->getHeaderInfo->{Name};
    next if $element_name =~ m{/$};      # Skip Directories
    my $element_dir = dirname $element_name;
    my $full_element_dir = File::Spec->join( $unzip_directory, $element_dir );
    #
    # Create the directory for the file if it doesn't exist
    #
    my $full_element_name = File::Spec->join( $unzip_directory, $element_name );
    if ( not -d $full_element_dir ) {
        make_path $full_element_dir
            or die qq(Can't make directory "$full_element_dir".);
    }
    my $unzipped_fh = IO::File->new( $full_element_name, "w" )
        or die qq(Can't open file "$full_element_name" for writing: $!);
    #
    # Now repeatably read the file until you've written everything
    #
    my $buffer;
    while ( my $status = $zip_fh->read( $buffer ) ) {
        if ( $status < 0 ) {
            die qq(Error in Zip: $IO::Uncompress::Unzip::UnzipError.);
        }
        $unzipped_fh->write( $buffer );
    }
    $unzipped_fh->close;
    $status = $zip_fh->nextStream; # Getting next file if any... or 0 to quit loop...
}
$zip_fh->close;

最新更新