我试图使用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";
}
我做错了什么?
我花了一些时间才弄清楚代码和语法。基本上,语法是:
- 打开压缩文件
- 读取下一个文件流(
nextStream
)时。- 查找正在读取的文件流的名称
- 创建一个新文件写入(使用
open
或File::IO->new
) - 当文件流中有数据时(
read
)- 写入新文件的缓冲区
- 关闭你创建的文件。
- 关闭压缩文件
的技巧是,如果读取有问题,两个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;