私はいくつかのコードスニペットと私の側からのいくつかの変更からまとめて、ファイルタイプを自動的に処理する圧縮解除機能を作成しました。Perl - Windows上でのzipファイルの圧縮が遅すぎる
私の現在のユースケースは、その中にたくさんのファイル(QT 5.5ソースコード)Linuxの
でWindows上のSMB共有から〜550メガバイトのzipファイルを抽出することで、これは、NFS共有上のtgzファイルがあります関数がそれを抽出するのに67秒かかります。 (zipファイル以外の圧縮解除方法)
Windowsでは15分以上かかります。
私は代わりにsystem(7z $ source)コールを使用することを考えています。
Windowsでzipファイルを解凍する最も速い方法は何ですか?
Plzをは...私の解凍機能ががらくたであるならば、私はperlの専門家だ、:)
正直言ってここに私のコードです:
#uncompress full archive file $archFile to $destPath
sub uncompress
{
my $fileToExtract = shift;
my $targetPath = shift;
my $silent = shift;
my $status;
my $buff;
unless (-f $fileToExtract)
{
&error ("$fileToExtract is not a file!");
}
unless (-d $targetPath)
{
&makeDir($targetPath, 1);
}
# just look for .tar since all .tar archives with all compressions can be extracted.
if ($fileToExtract =~ m/.tar/)
{
my $pwd = getcwd();
changeDirectory($targetPath, 1);
my $tar = Archive::Tar->new();
$tar->read($fileToExtract);
$tar->extract();
changeDirectory($pwd, 1);
return;
}
elsif ($fileToExtract =~ m/.zip$/)
{
my $u = new IO::Uncompress::Unzip $fileToExtract or die "Cannot open $fileToExtract: $UnzipError";
for ($status = 1; $status > 0; $status = $u->nextStream())
{
my $header = $u->getHeaderInfo();
my (undef, $path, $name) = splitpath($header->{Name});
my (undef, $path, $name) = splitpath($header->{Name});
my $destdir = "$targetPath$path";
unless (-d $destdir)
{
&makeDir($destdir, 1);
}
if ($name =~ m!/$!) {
last if $status < 0;
next;
}
my $destfile = "$destdir/$name";
if ($destfile =~ m/\/\/$/) # skip if no filename is given
{
next;
}
$destfile =~ s|\/\/|\/|g; # remove unnecessary doubleslashes
my $fh = openFileHandle ($destfile , '>', 1);
binmode($fh);
while (($status = $u->read($buff)) > 0) {
$fh->write($buff);
}
$fh->close();
unless (defined $silent)
{
&syslog ("Uncompress $destfile -> $targetPath");
}
#set timestamps of file to the ones in the zip
my $stored_time = $header->{'Time'};
utime ($stored_time, $stored_time, $destfile);
}
if ($status < 0)
{
die "Error processing $fileToExtract: $!\n"
}
}
else
{
my $ae = Archive::Extract->new(archive => $fileToExtract);
$ae->extract(to => $targetPath) or &error("Failed to extract $fileToExtract with error $ae->error");
unless (defined $silent)
{
foreach my $file (@{$ae->files})
{
#only print if not a directory
if($file!~m|/$|)
{
&syslog("Uncompress $fileToExtract -> $targetPath");
}
}
}
}
return;
}
ありがとうございました。 Archive :: Extractは、私が解凍機能を実装したときの最初の試みでした。いくつかのエラーメッセージが表示されます.zipファイルを解凍しようとすると、別の方法が使用されます。 ログの抜粋: フォーマットエラー:不正な署名は:0x302e352eがでファイルに539714421をオフセット\\ eisux242 \ ThirdParty_Dev_Tools \ Qt5 \ qt-everywhere-enterprise-src-5.5.0.zip Cで:\ Perl64 \ libに/アーカイブ/ Zip :: pm line 477.\t Archive :: Zip :: _ readSignature( 'IO :: File = GLOB(0x27139e0)'、 '\\ eisux242 \ ThirdParty_Dev_Tools \ Qt5 \ qt-everywhere-enterprise -...') C:¥Perl64¥lib/Archive/Zip/Archive.pm行603 – Chris
Btw、zipファイルが正常であるようです zip -T qt-everywhere-enterprise-src-5.5.0.zip qt-everywhereのテスト-enterprise-src-5.5.0.zip OK – Chris
私はそれを完了させ、19分かかりました。 2分長くしてから、以前に使用した関数(とエラーメッセージがたくさんあった):-( – Chris