2017-01-27 16 views
1

私はいくつかのコードスニペットと私の側からのいくつかの変更からまとめて、ファイルタイプを自動的に処理する圧縮解除機能を作成しました。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; 
} 

答えて

1

あなたは単に使用方法の下にそれを行うことができますArchive::Extractの場合、一般的なアーカイブ抽出メカニズムを提供するため、tarzipのモジュールを個別にインストールする必要はありません。

use Archive::Extract; 
my $ae = Archive::Extract->new(archive => $fileToExtract); 
my $ok = $ae->extract(to => $targetPath); 

あなたは、特にファイルがtarやzipであるかどうかを確認したい場合、あなたは以下を使用することができます:Archive::Extractはコアモジュールであるので、あなたはseparetelyそれをインストールする必要はありませんよということ

$ae->is_tar 
$ae->is_zip 

注意。

+0

ありがとうございました。 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

+0

Btw、zipファイルが正常であるようです zip -T qt-everywhere-enterprise-src-5.5.0.zip qt-everywhereのテスト-enterprise-src-5.5.0.zip OK – Chris

+0

私はそれを完了させ、19分かかりました。 2分長くしてから、以前に使用した関数(とエラーメッセージがたくさんあった):-( – Chris

関連する問題