⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 extract.pm

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 PM
📖 第 1 页 / 共 3 页
字号:
package Archive::Extract;use strict;use Cwd                         qw[cwd];use Carp                        qw[carp];use IPC::Cmd                    qw[run can_run];use FileHandle;use File::Path                  qw[mkpath];use File::Spec;use File::Basename              qw[dirname basename];use Params::Check               qw[check];use Module::Load::Conditional   qw[can_load check_install];use Locale::Maketext::Simple    Style => 'gettext';### solaris has silly /bin/tar output ###use constant ON_SOLARIS     => $^O eq 'solaris' ? 1 : 0;use constant FILE_EXISTS    => sub { -e $_[0] ? 1 : 0 };### VMS may require quoting upper case command optionsuse constant ON_VMS         => $^O eq 'VMS' ? 1 : 0;### If these are changed, update @TYPES and the new() PODuse constant TGZ            => 'tgz';use constant TAR            => 'tar';use constant GZ             => 'gz';use constant ZIP            => 'zip';use constant BZ2            => 'bz2';use constant TBZ            => 'tbz';use constant Z              => 'Z';use vars qw[$VERSION $PREFER_BIN $PROGRAMS $WARN $DEBUG];$VERSION        = '0.24';$PREFER_BIN     = 0;$WARN           = 1;$DEBUG          = 0;my @Types       = ( TGZ, TAR, GZ, ZIP, BZ2, TBZ, Z ); # same as all constantslocal $Params::Check::VERBOSE = $Params::Check::VERBOSE = 1;=pod=head1 NAMEArchive::Extract - A generic archive extracting mechanism=head1 SYNOPSIS    use Archive::Extract;    ### build an Archive::Extract object ###    my $ae = Archive::Extract->new( archive => 'foo.tgz' );    ### extract to cwd() ###    my $ok = $ae->extract;    ### extract to /tmp ###    my $ok = $ae->extract( to => '/tmp' );    ### what if something went wrong?    my $ok = $ae->extract or die $ae->error;    ### files from the archive ###    my $files   = $ae->files;    ### dir that was extracted to ###    my $outdir  = $ae->extract_path;    ### quick check methods ###    $ae->is_tar     # is it a .tar file?    $ae->is_tgz     # is it a .tar.gz or .tgz file?    $ae->is_gz;     # is it a .gz file?    $ae->is_zip;    # is it a .zip file?    $ae->is_bz2;    # is it a .bz2 file?    $ae->is_tbz;    # is it a .tar.bz2 or .tbz file?    ### absolute path to the archive you provided ###    $ae->archive;    ### commandline tools, if found ###    $ae->bin_tar     # path to /bin/tar, if found    $ae->bin_gzip    # path to /bin/gzip, if found    $ae->bin_unzip   # path to /bin/unzip, if found    $ae->bin_bunzip2 # path to /bin/bunzip2 if found=head1 DESCRIPTIONArchive::Extract is a generic archive extraction mechanism.It allows you to extract any archive file of the type .tar, .tar.gz,.gz, .Z, tar.bz2, .tbz, .bz2 or .zip without having to worry how it does so, or use different interfaces for each type by using either perl modules, or commandline tools on your system.See the C<HOW IT WORKS> section further down for details.=cut### see what /bin/programs are available ###$PROGRAMS = {};for my $pgm (qw[tar unzip gzip bunzip2 uncompress]) {    $PROGRAMS->{$pgm} = can_run($pgm);}### mapping from types to extractor methods ###my $Mapping = {    is_tgz  => '_untar',    is_tar  => '_untar',    is_gz   => '_gunzip',    is_zip  => '_unzip',    is_tbz  => '_untar',    is_bz2  => '_bunzip2',    is_Z    => '_uncompress',};{    my $tmpl = {        archive => { required => 1, allow => FILE_EXISTS },        type    => { default => '', allow => [ @Types ] },    };    ### build accesssors ###    for my $method( keys %$tmpl,                     qw[_extractor _gunzip_to files extract_path],                    qw[_error_msg _error_msg_long]    ) {        no strict 'refs';        *$method = sub {                        my $self = shift;                        $self->{$method} = $_[0] if @_;                        return $self->{$method};                    }    }=head1 METHODS=head2 $ae = Archive::Extract->new(archive => '/path/to/archive',[type => TYPE])Creates a new C<Archive::Extract> object based on the archive file youpassed it. Automatically determines the type of archive based on theextension, but you can override that by explicitly providing theC<type> argument.Valid values for C<type> are:=over 4=item tarStandard tar files, as produced by, for example, C</bin/tar>.Corresponds to a C<.tar> suffix.=item tgzGzip compressed tar files, as produced by, for example C</bin/tar -z>.Corresponds to a C<.tgz> or C<.tar.gz> suffix.=item gzGzip compressed file, as produced by, for example C</bin/gzip>.Corresponds to a C<.gz> suffix.=item ZLempel-Ziv compressed file, as produced by, for example C</bin/compress>.Corresponds to a C<.Z> suffix.=item zipZip compressed file, as produced by, for example C</bin/zip>.Corresponds to a C<.zip>, C<.jar> or C<.par> suffix.=item bz2Bzip2 compressed file, as produced by, for example, C</bin/bzip2>.Corresponds to a C<.bz2> suffix.=item tbzBzip2 compressed tar file, as produced by, for exmample C</bin/tar -j>.Corresponds to a C<.tbz> or C<.tar.bz2> suffix.=backReturns a C<Archive::Extract> object on success, or false on failure.=cut    ### constructor ###    sub new {        my $class   = shift;        my %hash    = @_;        my $parsed = check( $tmpl, \%hash ) or return;        ### make sure we have an absolute path ###        my $ar = $parsed->{archive} = File::Spec->rel2abs( $parsed->{archive} );        ### figure out the type, if it wasn't already specified ###        unless ( $parsed->{type} ) {            $parsed->{type} =                $ar =~ /.+?\.(?:tar\.gz|tgz)$/i     ? TGZ   :                $ar =~ /.+?\.gz$/i                  ? GZ    :                $ar =~ /.+?\.tar$/i                 ? TAR   :                $ar =~ /.+?\.(zip|jar|par)$/i       ? ZIP   :                $ar =~ /.+?\.(?:tbz2?|tar\.bz2?)$/i ? TBZ   :                $ar =~ /.+?\.bz2$/i                 ? BZ2   :                $ar =~ /.+?\.Z$/                    ? Z     :                '';        }        ### don't know what type of file it is ###        return __PACKAGE__->_error(loc("Cannot determine file type for '%1'",                                $parsed->{archive} )) unless $parsed->{type};        return bless $parsed, $class;    }}=head2 $ae->extract( [to => '/output/path'] )Extracts the archive represented by the C<Archive::Extract> object tothe path of your choice as specified by the C<to> argument. Defaults toC<cwd()>.Since C<.gz> files never hold a directory, but only a single file; if the C<to> argument is an existing directory, the file is extracted there, with it's C<.gz> suffix stripped. If the C<to> argument is not an existing directory, the C<to> argument is understood to be a filename, if the archive type is C<gz>. In the case that you did not specify a C<to> argument, the outputfile will be the name of the archive file, stripped from it's C<.gz>suffix, in the current working directory.C<extract> will try a pure perl solution first, and then fall back tocommandline tools if they are available. See the C<GLOBAL VARIABLES>section below on how to alter this behaviour.It will return true on success, and false on failure.On success, it will also set the follow attributes in the object:=over 4=item $ae->extract_pathThis is the directory that the files where extracted to.=item $ae->filesThis is an array ref with the paths of all the files in the archive,relative to the C<to> argument you specified.To get the full path to an extracted file, you would use:    File::Spec->catfile( $to, $ae->files->[0] );Note that all files from a tar archive will be in unix format, as perthe tar specification.=back=cutsub extract {    my $self = shift;    my %hash = @_;    my $to;    my $tmpl = {        to  => { default => '.', store => \$to }    };    check( $tmpl, \%hash ) or return;    ### so 'to' could be a file or a dir, depending on whether it's a .gz     ### file, or basically anything else.    ### so, check that, then act accordingly.    ### set an accessor specifically so _gunzip can know what file to extract    ### to.    my $dir;    {   ### a foo.gz file        if( $self->is_gz or $self->is_bz2 or $self->is_Z) {                my $cp = $self->archive; $cp =~ s/\.(?:gz|bz2?|Z)$//i;                    ### to is a dir?            if ( -d $to ) {                $dir = $to;                 $self->_gunzip_to( basename($cp) );            ### then it's a filename            } else {                $dir = dirname($to);                $self->_gunzip_to( basename($to) );            }        ### not a foo.gz file        } else {            $dir = $to;        }    }    ### make the dir if it doesn't exist ###    unless( -d $dir ) {        eval { mkpath( $dir ) };        return $self->_error(loc("Could not create path '%1': %2", $dir, $@))            if $@;    }    ### get the current dir, to restore later ###    my $cwd = cwd();    my $ok = 1;    EXTRACT: {        ### chdir to the target dir ###        unless( chdir $dir ) {            $self->_error(loc("Could not chdir to '%1': %2", $dir, $!));            $ok = 0; last EXTRACT;        }        ### set files to an empty array ref, so there's always an array        ### ref IN the accessor, to avoid errors like:        ### Can't use an undefined value as an ARRAY reference at        ### ../lib/Archive/Extract.pm line 742. (rt #19815)        $self->files( [] );        ### find what extractor method to use ###        while( my($type,$method) = each %$Mapping ) {            ### call the corresponding method if the type is OK ###            if( $self->$type) {                $ok = $self->$method();            }        }        ### warn something went wrong if we didn't get an OK ###        $self->_error(loc("Extract failed, no extractor found"))            unless $ok;    }    ### and chdir back ###    unless( chdir $cwd ) {        $self->_error(loc("Could not chdir back to start dir '%1': %2'",                            $cwd, $!));    }    return $ok;}=pod=head1 ACCESSORS=head2 $ae->error([BOOL])Returns the last encountered error as string.Pass it a true value to get the C<Carp::longmess()> output instead.=head2 $ae->extract_pathThis is the directory the archive got extracted to.See C<extract()> for details.=head2 $ae->filesThis is an array ref holding all the paths from the archive.See C<extract()> for details.=head2 $ae->archiveThis is the full path to the archive file represented by thisC<Archive::Extract> object.=head2 $ae->typeThis is the type of archive represented by this C<Archive::Extract>object. See accessors below for an easier way to use this.See the C<new()> method for details.=head2 $ae->typesReturns a list of all known C<types> for C<Archive::Extract>'sC<new> method.=cutsub types { return @Types }=head2 $ae->is_tgzReturns true if the file is of type C<.tar.gz>.See the C<new()> method for details.=head2 $ae->is_tarReturns true if the file is of type C<.tar>.See the C<new()> method for details.=head2 $ae->is_gzReturns true if the file is of type C<.gz>.See the C<new()> method for details.=head2 $ae->is_ZReturns true if the file is of type C<.Z>.See the C<new()> method for details.=head2 $ae->is_zipReturns true if the file is of type C<.zip>.See the C<new()> method for details.=cut### quick check methods ###sub is_tgz  { return $_[0]->type eq TGZ }sub is_tar  { return $_[0]->type eq TAR }sub is_gz   { return $_[0]->type eq GZ  }sub is_zip  { return $_[0]->type eq ZIP }sub is_tbz  { return $_[0]->type eq TBZ }sub is_bz2  { return $_[0]->type eq BZ2 }sub is_Z    { return $_[0]->type eq Z   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -