1package IO::Compress::Zip ; 2 3use strict ; 4use warnings; 5use bytes; 6 7use IO::Compress::Base::Common 2.212 qw(:Status ); 8use IO::Compress::RawDeflate 2.212 (); 9use IO::Compress::Adapter::Deflate 2.212 ; 10use IO::Compress::Adapter::Identity 2.212 ; 11use IO::Compress::Zlib::Extra 2.212 ; 12use IO::Compress::Zip::Constants 2.212 ; 13 14use File::Spec(); 15use Config; 16 17use Compress::Raw::Zlib 2.212 (); 18 19BEGIN 20{ 21 eval { require IO::Compress::Adapter::Bzip2 ; 22 IO::Compress::Adapter::Bzip2->VERSION( 2.212 ); 23 require IO::Compress::Bzip2 ; 24 IO::Compress::Bzip2->VERSION( 2.212 ); 25 } ; 26 27 eval { require IO::Compress::Adapter::Lzma ; 28 IO::Compress::Adapter::Lzma->VERSION( 2.212 ); 29 require IO::Compress::Lzma ; 30 IO::Compress::Lzma->VERSION( 2.212 ); 31 } ; 32 33 eval { require IO::Compress::Adapter::Xz ; 34 IO::Compress::Adapter::Xz->VERSION( 2.212 ); 35 require IO::Compress::Xz ; 36 IO::Compress::Xz->VERSION( 2.212 ); 37 } ; 38 eval { require IO::Compress::Adapter::Zstd ; 39 IO::Compress::Adapter::Zstd->VERSION( 2.212 ); 40 require IO::Compress::Zstd ; 41 IO::Compress::Zstd->VERSION( 2.212 ); 42 } ; 43} 44 45 46require Exporter ; 47 48our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, %DEFLATE_CONSTANTS, $ZipError); 49 50$VERSION = '2.212'; 51$ZipError = ''; 52 53@ISA = qw(IO::Compress::RawDeflate Exporter); 54@EXPORT_OK = qw( $ZipError zip ) ; 55%EXPORT_TAGS = %IO::Compress::RawDeflate::DEFLATE_CONSTANTS ; 56 57push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ; 58 59$EXPORT_TAGS{zip_method} = [qw( ZIP_CM_STORE ZIP_CM_DEFLATE ZIP_CM_BZIP2 ZIP_CM_LZMA ZIP_CM_XZ ZIP_CM_ZSTD)]; 60push @{ $EXPORT_TAGS{all} }, @{ $EXPORT_TAGS{zip_method} }; 61 62Exporter::export_ok_tags('all'); 63 64sub new 65{ 66 my $class = shift ; 67 68 my $obj = IO::Compress::Base::Common::createSelfTiedObject($class, \$ZipError); 69 $obj->_create(undef, @_); 70 71} 72 73sub zip 74{ 75 my $obj = IO::Compress::Base::Common::createSelfTiedObject(undef, \$ZipError); 76 return $obj->_def(@_); 77} 78 79sub isMethodAvailable 80{ 81 my $method = shift; 82 83 # Store & Deflate are always available 84 return 1 85 if $method == ZIP_CM_STORE || $method == ZIP_CM_DEFLATE ; 86 87 return 1 88 if $method == ZIP_CM_BZIP2 && 89 defined $IO::Compress::Adapter::Bzip2::VERSION && 90 defined &{ "IO::Compress::Adapter::Bzip2::mkRawZipCompObject" }; 91 92 return 1 93 if $method == ZIP_CM_LZMA && 94 defined $IO::Compress::Adapter::Lzma::VERSION && 95 defined &{ "IO::Compress::Adapter::Lzma::mkRawZipCompObject" }; 96 97 return 1 98 if $method == ZIP_CM_XZ && 99 defined $IO::Compress::Adapter::Xz::VERSION && 100 defined &{ "IO::Compress::Adapter::Xz::mkRawZipCompObject" }; 101 102 return 1 103 if $method == ZIP_CM_ZSTD && 104 defined $IO::Compress::Adapter::ZSTD::VERSION && 105 defined &{ "IO::Compress::Adapter::ZSTD::mkRawZipCompObject" }; 106 107 return 0; 108} 109 110sub beforePayload 111{ 112 my $self = shift ; 113 114 if (*$self->{ZipData}{Sparse} ) { 115 my $inc = 1024 * 100 ; 116 my $NULLS = ("\x00" x $inc) ; 117 my $sparse = *$self->{ZipData}{Sparse} ; 118 *$self->{CompSize}->add( $sparse ); 119 *$self->{UnCompSize}->add( $sparse ); 120 121 *$self->{FH}->seek($sparse, IO::Handle::SEEK_CUR); 122 123 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32($NULLS, *$self->{ZipData}{CRC32}) 124 for 1 .. int $sparse / $inc; 125 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(substr($NULLS, 0, $sparse % $inc), 126 *$self->{ZipData}{CRC32}) 127 if $sparse % $inc; 128 } 129} 130 131sub mkComp 132{ 133 my $self = shift ; 134 my $got = shift ; 135 136 my ($obj, $errstr, $errno) ; 137 138 if (*$self->{ZipData}{Method} == ZIP_CM_STORE) { 139 ($obj, $errstr, $errno) = IO::Compress::Adapter::Identity::mkCompObject( 140 $got->getValue('level'), 141 $got->getValue('strategy') 142 ); 143 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef); 144 } 145 elsif (*$self->{ZipData}{Method} == ZIP_CM_DEFLATE) { 146 ($obj, $errstr, $errno) = IO::Compress::Adapter::Deflate::mkCompObject( 147 $got->getValue('crc32'), 148 $got->getValue('adler32'), 149 $got->getValue('level'), 150 $got->getValue('strategy') 151 ); 152 } 153 elsif (*$self->{ZipData}{Method} == ZIP_CM_BZIP2) { 154 ($obj, $errstr, $errno) = IO::Compress::Adapter::Bzip2::mkCompObject( 155 $got->getValue('blocksize100k'), 156 $got->getValue('workfactor'), 157 $got->getValue('verbosity') 158 ); 159 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef); 160 } 161 elsif (*$self->{ZipData}{Method} == ZIP_CM_LZMA) { 162 ($obj, $errstr, $errno) = IO::Compress::Adapter::Lzma::mkRawZipCompObject($got->getValue('preset'), 163 $got->getValue('extreme'), 164 ); 165 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef); 166 } 167 elsif (*$self->{ZipData}{Method} == ZIP_CM_XZ) { 168 ($obj, $errstr, $errno) = IO::Compress::Adapter::Xz::mkCompObject($got->getValue('preset'), 169 $got->getValue('extreme'), 170 0 171 ); 172 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef); 173 } 174 elsif (*$self->{ZipData}{Method} == ZIP_CM_ZSTD) { 175 ($obj, $errstr, $errno) = IO::Compress::Adapter::Zstd::mkCompObject(defined $got->getValue('level') ? $got->getValue('level') : 3, 176 ); 177 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef); 178 } 179 180 return $self->saveErrorString(undef, $errstr, $errno) 181 if ! defined $obj; 182 183 if (! defined *$self->{ZipData}{SizesOffset}) { 184 *$self->{ZipData}{SizesOffset} = 0; 185 *$self->{ZipData}{Offset} = U64->new(); 186 } 187 188 *$self->{ZipData}{AnyZip64} = 0 189 if ! defined *$self->{ZipData}{AnyZip64} ; 190 191 return $obj; 192} 193 194sub reset 195{ 196 my $self = shift ; 197 198 *$self->{Compress}->reset(); 199 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(''); 200 201 return STATUS_OK; 202} 203 204sub filterUncompressed 205{ 206 my $self = shift ; 207 208 if (*$self->{ZipData}{Method} == ZIP_CM_DEFLATE) { 209 *$self->{ZipData}{CRC32} = *$self->{Compress}->crc32(); 210 } 211 else { 212 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(${$_[0]}, *$self->{ZipData}{CRC32}); 213 214 } 215} 216 217sub canonicalName 218{ 219 # This sub is derived from Archive::Zip::_asZipDirName 220 221 # Return the normalized name as used in a zip file (path 222 # separators become slashes, etc.). 223 # Will translate internal slashes in path components (i.e. on Macs) to 224 # underscores. Discards volume names. 225 # When $forceDir is set, returns paths with trailing slashes 226 # 227 # input output 228 # . '.' 229 # ./a a 230 # ./a/b a/b 231 # ./a/b/ a/b 232 # a/b/ a/b 233 # /a/b/ a/b 234 # c:\a\b\c.doc a/b/c.doc # on Windows 235 # "i/o maps:whatever" i_o maps/whatever # on Macs 236 237 my $name = shift; 238 my $forceDir = shift ; 239 240 my ( $volume, $directories, $file ) = 241 File::Spec->splitpath( File::Spec->canonpath($name), $forceDir ); 242 243 my @dirs = map { $_ =~ s{/}{_}g; $_ } 244 File::Spec->splitdir($directories); 245 246 if ( @dirs > 0 ) { pop (@dirs) if $dirs[-1] eq '' } # remove empty component 247 push @dirs, defined($file) ? $file : '' ; 248 249 my $normalised_path = join '/', @dirs; 250 251 # Leading directory separators should not be stored in zip archives. 252 # Example: 253 # C:\a\b\c\ a/b/c 254 # C:\a\b\c.txt a/b/c.txt 255 # /a/b/c/ a/b/c 256 # /a/b/c.txt a/b/c.txt 257 $normalised_path =~ s{^/}{}; # remove leading separator 258 259 return $normalised_path; 260} 261 262 263sub mkHeader 264{ 265 my $self = shift; 266 my $param = shift ; 267 268 *$self->{ZipData}{LocalHdrOffset} = U64::clone(*$self->{ZipData}{Offset}); 269 270 my $comment = ''; 271 $comment = $param->valueOrDefault('comment') ; 272 273 my $filename = ''; 274 $filename = $param->valueOrDefault('name') ; 275 276 $filename = canonicalName($filename) 277 if length $filename && $param->getValue('canonicalname') ; 278 279 if (defined *$self->{ZipData}{FilterName} ) { 280 local *_ = \$filename ; 281 &{ *$self->{ZipData}{FilterName} }() ; 282 } 283 284 if ( $param->getValue('efs') && $] >= 5.008004) { 285 if (length $filename) { 286 utf8::downgrade($filename, 1) 287 or Carp::croak "Wide character in zip filename"; 288 } 289 290 if (length $comment) { 291 utf8::downgrade($comment, 1) 292 or Carp::croak "Wide character in zip comment"; 293 } 294 } 295 296 my $hdr = ''; 297 298 my $time = _unixToDosTime($param->getValue('time')); 299 300 my $extra = ''; 301 my $ctlExtra = ''; 302 my $empty = 0; 303 my $osCode = $param->getValue('os_code') ; 304 my $extFileAttr = 0 ; 305 306 # This code assumes Unix. 307 # TODO - revisit this 308 $extFileAttr = 0100644 << 16 309 if $osCode == ZIP_OS_CODE_UNIX ; 310 311 if (*$self->{ZipData}{Zip64}) { 312 $empty = IO::Compress::Base::Common::MAX32; 313 314 my $x = ''; 315 $x .= pack "V V", 0, 0 ; # uncompressedLength 316 $x .= pack "V V", 0, 0 ; # compressedLength 317 318 # Zip64 needs to be first in extra field to workaround a Windows Explorer Bug 319 # See http://www.info-zip.org/phpBB3/viewtopic.php?f=3&t=440 for details 320 $extra .= IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_ZIP64, $x); 321 } 322 323 if (! $param->getValue('minimal')) { 324 if ($param->parsed('mtime')) 325 { 326 $extra .= mkExtendedTime($param->getValue('mtime'), 327 $param->getValue('atime'), 328 $param->getValue('ctime')); 329 330 $ctlExtra .= mkExtendedTime($param->getValue('mtime')); 331 } 332 333 if ( $osCode == ZIP_OS_CODE_UNIX ) 334 { 335 if ( $param->getValue('want_exunixn') ) 336 { 337 my $ux3 = mkUnixNExtra( @{ $param->getValue('want_exunixn') }); 338 $extra .= $ux3; 339 $ctlExtra .= $ux3; 340 } 341 342 if ( $param->getValue('exunix2') ) 343 { 344 $extra .= mkUnix2Extra( @{ $param->getValue('exunix2') }); 345 $ctlExtra .= mkUnix2Extra(); 346 } 347 } 348 349 $extFileAttr = $param->getValue('extattr') 350 if defined $param->getValue('extattr') ; 351 352 $extra .= $param->getValue('extrafieldlocal') 353 if defined $param->getValue('extrafieldlocal'); 354 355 $ctlExtra .= $param->getValue('extrafieldcentral') 356 if defined $param->getValue('extrafieldcentral'); 357 } 358 359 my $method = *$self->{ZipData}{Method} ; 360 my $gpFlag = 0 ; 361 $gpFlag |= ZIP_GP_FLAG_STREAMING_MASK 362 if *$self->{ZipData}{Stream} ; 363 364 $gpFlag |= ZIP_GP_FLAG_LZMA_EOS_PRESENT 365 if $method == ZIP_CM_LZMA ; 366 367 $gpFlag |= ZIP_GP_FLAG_LANGUAGE_ENCODING 368 if $param->getValue('efs') && (length($filename) || length($comment)); 369 370 my $version = $ZIP_CM_MIN_VERSIONS{$method}; 371 $version = ZIP64_MIN_VERSION 372 if ZIP64_MIN_VERSION > $version && *$self->{ZipData}{Zip64}; 373 374 my $madeBy = ($param->getValue('os_code') << 8) + $version; 375 my $extract = $version; 376 377 *$self->{ZipData}{Version} = $version; 378 *$self->{ZipData}{MadeBy} = $madeBy; 379 380 my $ifa = 0; 381 $ifa |= ZIP_IFA_TEXT_MASK 382 if $param->getValue('textflag'); 383 384 $hdr .= pack "V", ZIP_LOCAL_HDR_SIG ; # signature 385 $hdr .= pack 'v', $extract ; # extract Version & OS 386 $hdr .= pack 'v', $gpFlag ; # general purpose flag (set streaming mode) 387 $hdr .= pack 'v', $method ; # compression method (deflate) 388 $hdr .= pack 'V', $time ; # last mod date/time 389 $hdr .= pack 'V', 0 ; # crc32 - 0 when streaming 390 $hdr .= pack 'V', $empty ; # compressed length - 0 when streaming 391 $hdr .= pack 'V', $empty ; # uncompressed length - 0 when streaming 392 $hdr .= pack 'v', length $filename ; # filename length 393 $hdr .= pack 'v', length $extra ; # extra length 394 395 $hdr .= $filename ; 396 397 # Remember the offset for the compressed & uncompressed lengths in the 398 # local header. 399 if (*$self->{ZipData}{Zip64}) { 400 *$self->{ZipData}{SizesOffset} = *$self->{ZipData}{Offset}->get64bit() 401 + length($hdr) + 4 ; 402 } 403 else { 404 *$self->{ZipData}{SizesOffset} = *$self->{ZipData}{Offset}->get64bit() 405 + 18; 406 } 407 408 $hdr .= $extra ; 409 410 411 my $ctl = ''; 412 413 $ctl .= pack "V", ZIP_CENTRAL_HDR_SIG ; # signature 414 $ctl .= pack 'v', $madeBy ; # version made by 415 $ctl .= pack 'v', $extract ; # extract Version 416 $ctl .= pack 'v', $gpFlag ; # general purpose flag (streaming mode) 417 $ctl .= pack 'v', $method ; # compression method (deflate) 418 $ctl .= pack 'V', $time ; # last mod date/time 419 $ctl .= pack 'V', 0 ; # crc32 420 $ctl .= pack 'V', $empty ; # compressed length 421 $ctl .= pack 'V', $empty ; # uncompressed length 422 $ctl .= pack 'v', length $filename ; # filename length 423 424 *$self->{ZipData}{ExtraOffset} = length $ctl; 425 *$self->{ZipData}{ExtraSize} = length $ctlExtra ; 426 427 $ctl .= pack 'v', length $ctlExtra ; # extra length 428 $ctl .= pack 'v', length $comment ; # file comment length 429 $ctl .= pack 'v', 0 ; # disk number start 430 $ctl .= pack 'v', $ifa ; # internal file attributes 431 $ctl .= pack 'V', $extFileAttr ; # external file attributes 432 433 # offset to local hdr 434 if (*$self->{ZipData}{LocalHdrOffset}->is64bit() ) { 435 $ctl .= pack 'V', IO::Compress::Base::Common::MAX32 ; 436 } 437 else { 438 $ctl .= *$self->{ZipData}{LocalHdrOffset}->getPacked_V32() ; 439 } 440 441 $ctl .= $filename ; 442 443 *$self->{ZipData}{Offset}->add32(length $hdr) ; 444 445 *$self->{ZipData}{CentralHeader} = [ $ctl, $ctlExtra, $comment]; 446 447 return $hdr; 448} 449 450sub mkTrailer 451{ 452 my $self = shift ; 453 454 my $crc32 ; 455 if (*$self->{ZipData}{Method} == ZIP_CM_DEFLATE) { 456 $crc32 = pack "V", *$self->{Compress}->crc32(); 457 } 458 else { 459 $crc32 = pack "V", *$self->{ZipData}{CRC32}; 460 } 461 462 my ($ctl, $ctlExtra, $comment) = @{ *$self->{ZipData}{CentralHeader} }; 463 464 my $sizes ; 465 if (! *$self->{ZipData}{Zip64}) { 466 $sizes .= *$self->{CompSize}->getPacked_V32() ; # Compressed size 467 $sizes .= *$self->{UnCompSize}->getPacked_V32() ; # Uncompressed size 468 } 469 else { 470 $sizes .= *$self->{CompSize}->getPacked_V64() ; # Compressed size 471 $sizes .= *$self->{UnCompSize}->getPacked_V64() ; # Uncompressed size 472 } 473 474 my $data = $crc32 . $sizes ; 475 476 my $xtrasize = *$self->{UnCompSize}->getPacked_V64() ; # Uncompressed size 477 $xtrasize .= *$self->{CompSize}->getPacked_V64() ; # Compressed size 478 479 my $hdr = ''; 480 481 if (*$self->{ZipData}{Stream}) { 482 $hdr = pack "V", ZIP_DATA_HDR_SIG ; # signature 483 $hdr .= $data ; 484 } 485 else { 486 $self->writeAt(*$self->{ZipData}{LocalHdrOffset}->get64bit() + 14, $crc32) 487 or return undef; 488 $self->writeAt(*$self->{ZipData}{SizesOffset}, 489 *$self->{ZipData}{Zip64} ? $xtrasize : $sizes) 490 or return undef; 491 } 492 493 # Central Header Record/Zip64 extended field 494 495 substr($ctl, 16, length $crc32) = $crc32 ; 496 497 my $zip64Payload = ''; 498 499 # uncompressed length - only set zip64 if needed 500 if (*$self->{UnCompSize}->isAlmost64bit()) { # || *$self->{ZipData}{Zip64}) { 501 $zip64Payload .= *$self->{UnCompSize}->getPacked_V64() ; 502 } else { 503 substr($ctl, 24, 4) = *$self->{UnCompSize}->getPacked_V32() ; 504 } 505 506 # compressed length - only set zip64 if needed 507 if (*$self->{CompSize}->isAlmost64bit()) { # || *$self->{ZipData}{Zip64}) { 508 $zip64Payload .= *$self->{CompSize}->getPacked_V64() ; 509 } else { 510 substr($ctl, 20, 4) = *$self->{CompSize}->getPacked_V32() ; 511 } 512 513 # Local Header offset 514 $zip64Payload .= *$self->{ZipData}{LocalHdrOffset}->getPacked_V64() 515 if *$self->{ZipData}{LocalHdrOffset}->is64bit() ; 516 517 # disk no - always zero, so don't need to include it. 518 #$zip64Payload .= pack "V", 0 ; 519 520 my $zip64Xtra = ''; 521 522 if (length $zip64Payload) { 523 $zip64Xtra = IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_ZIP64, $zip64Payload); 524 525 substr($ctl, *$self->{ZipData}{ExtraOffset}, 2) = 526 pack 'v', *$self->{ZipData}{ExtraSize} + length $zip64Xtra; 527 528 *$self->{ZipData}{AnyZip64} = 1; 529 } 530 531 # Zip64 needs to be first in extra field to workaround a Windows Explorer Bug 532 # See http://www.info-zip.org/phpBB3/viewtopic.php?f=3&t=440 for details 533 $ctl .= $zip64Xtra . $ctlExtra . $comment; 534 535 *$self->{ZipData}{Offset}->add32(length($hdr)); 536 *$self->{ZipData}{Offset}->add( *$self->{CompSize} ); 537 push @{ *$self->{ZipData}{CentralDir} }, $ctl ; 538 539 return $hdr; 540} 541 542sub mkFinalTrailer 543{ 544 my $self = shift ; 545 546 my $comment = ''; 547 $comment = *$self->{ZipData}{ZipComment} ; 548 549 my $cd_offset = *$self->{ZipData}{Offset}->get32bit() ; # offset to start central dir 550 551 my $entries = @{ *$self->{ZipData}{CentralDir} }; 552 553 *$self->{ZipData}{AnyZip64} = 1 554 if *$self->{ZipData}{Offset}->is64bit || $entries >= 0xFFFF ; 555 556 my $cd = join '', @{ *$self->{ZipData}{CentralDir} }; 557 my $cd_len = length $cd ; 558 559 my $z64e = ''; 560 561 if ( *$self->{ZipData}{AnyZip64} ) { 562 563 my $v = *$self->{ZipData}{Version} ; 564 my $mb = *$self->{ZipData}{MadeBy} ; 565 $z64e .= pack 'v', $mb ; # Version made by 566 $z64e .= pack 'v', $v ; # Version to extract 567 $z64e .= pack 'V', 0 ; # number of disk 568 $z64e .= pack 'V', 0 ; # number of disk with central dir 569 $z64e .= U64::pack_V64 $entries ; # entries in central dir on this disk 570 $z64e .= U64::pack_V64 $entries ; # entries in central dir 571 $z64e .= U64::pack_V64 $cd_len ; # size of central dir 572 $z64e .= *$self->{ZipData}{Offset}->getPacked_V64() ; # offset to start central dir 573 $z64e .= *$self->{ZipData}{extrafieldzip64} # otional extra field 574 if defined *$self->{ZipData}{extrafieldzip64} ; 575 576 $z64e = pack("V", ZIP64_END_CENTRAL_REC_HDR_SIG) # signature 577 . U64::pack_V64(length $z64e) 578 . $z64e ; 579 580 *$self->{ZipData}{Offset}->add32(length $cd) ; 581 582 $z64e .= pack "V", ZIP64_END_CENTRAL_LOC_HDR_SIG; # signature 583 $z64e .= pack 'V', 0 ; # number of disk with central dir 584 $z64e .= *$self->{ZipData}{Offset}->getPacked_V64() ; # offset to end zip64 central dir 585 $z64e .= pack 'V', 1 ; # Total number of disks 586 587 $cd_offset = IO::Compress::Base::Common::MAX32 ; 588 $cd_len = IO::Compress::Base::Common::MAX32 if IO::Compress::Base::Common::isGeMax32 $cd_len ; 589 $entries = 0xFFFF if $entries >= 0xFFFF ; 590 } 591 592 my $ecd = ''; 593 $ecd .= pack "V", ZIP_END_CENTRAL_HDR_SIG ; # signature 594 $ecd .= pack 'v', 0 ; # number of disk 595 $ecd .= pack 'v', 0 ; # number of disk with central dir 596 $ecd .= pack 'v', $entries ; # entries in central dir on this disk 597 $ecd .= pack 'v', $entries ; # entries in central dir 598 $ecd .= pack 'V', $cd_len ; # size of central dir 599 $ecd .= pack 'V', $cd_offset ; # offset to start central dir 600 $ecd .= pack 'v', length $comment ; # zipfile comment length 601 $ecd .= $comment; 602 603 return $cd . $z64e . $ecd ; 604} 605 606sub ckParams 607{ 608 my $self = shift ; 609 my $got = shift; 610 611 $got->setValue('crc32' => 1); 612 613 if (! $got->parsed('time') ) { 614 # Modification time defaults to now. 615 $got->setValue('time' => time) ; 616 } 617 618 if ($got->parsed('extime') ) { 619 my $timeRef = $got->getValue('extime'); 620 if ( defined $timeRef) { 621 return $self->saveErrorString(undef, "exTime not a 3-element array ref") 622 if ref $timeRef ne 'ARRAY' || @$timeRef != 3; 623 } 624 625 $got->setValue("mtime", $timeRef->[1]); 626 $got->setValue("atime", $timeRef->[0]); 627 $got->setValue("ctime", $timeRef->[2]); 628 } 629 630 # Unix2/3 Extended Attribute 631 for my $name (qw(exunix2 exunixn)) 632 { 633 if ($got->parsed($name) ) { 634 my $idRef = $got->getValue($name); 635 if ( defined $idRef) { 636 return $self->saveErrorString(undef, "$name not a 2-element array ref") 637 if ref $idRef ne 'ARRAY' || @$idRef != 2; 638 } 639 640 $got->setValue("uid", $idRef->[0]); 641 $got->setValue("gid", $idRef->[1]); 642 $got->setValue("want_$name", $idRef); 643 } 644 } 645 646 *$self->{ZipData}{AnyZip64} = 1 647 if $got->getValue('zip64') || $got->getValue('extrafieldzip64') ; 648 *$self->{ZipData}{Zip64} = $got->getValue('zip64'); 649 *$self->{ZipData}{Stream} = $got->getValue('stream'); 650 651 my $method = $got->getValue('method'); 652 return $self->saveErrorString(undef, "Unknown Method '$method'") 653 if ! defined $ZIP_CM_MIN_VERSIONS{$method}; 654 655 return $self->saveErrorString(undef, "Bzip2 not available") 656 if $method == ZIP_CM_BZIP2 and 657 ! defined $IO::Compress::Adapter::Bzip2::VERSION; 658 659 return $self->saveErrorString(undef, "Lzma not available") 660 if $method == ZIP_CM_LZMA 661 and ! defined $IO::Compress::Adapter::Lzma::VERSION; 662 663 *$self->{ZipData}{Method} = $method; 664 665 *$self->{ZipData}{ZipComment} = $got->getValue('zipcomment') ; 666 667 for my $name (qw( extrafieldlocal extrafieldcentral extrafieldzip64)) 668 { 669 my $data = $got->getValue($name) ; 670 if (defined $data) { 671 my $bad = IO::Compress::Zlib::Extra::parseExtraField($data, 1, 0) ; 672 return $self->saveErrorString(undef, "Error with $name Parameter: $bad") 673 if $bad ; 674 675 $got->setValue($name, $data) ; 676 *$self->{ZipData}{$name} = $data; 677 } 678 } 679 680 return undef 681 if defined $IO::Compress::Bzip2::VERSION 682 and ! IO::Compress::Bzip2::ckParams($self, $got); 683 684 if ($got->parsed('sparse') ) { 685 *$self->{ZipData}{Sparse} = $got->getValue('sparse') ; 686 *$self->{ZipData}{Method} = ZIP_CM_STORE; 687 } 688 689 if ($got->parsed('filtername')) { 690 my $v = $got->getValue('filtername') ; 691 *$self->{ZipData}{FilterName} = $v 692 if ref $v eq 'CODE' ; 693 } 694 695 return 1 ; 696} 697 698sub outputPayload 699{ 700 my $self = shift ; 701 return 1 if *$self->{ZipData}{Sparse} ; 702 return $self->output(@_); 703} 704 705 706#sub newHeader 707#{ 708# my $self = shift ; 709# 710# return $self->mkHeader(*$self->{Got}); 711#} 712 713 714our %PARAMS = ( 715 'stream' => [IO::Compress::Base::Common::Parse_boolean, 1], 716 #'store' => [IO::Compress::Base::Common::Parse_boolean, 0], 717 'method' => [IO::Compress::Base::Common::Parse_unsigned, ZIP_CM_DEFLATE], 718 719# # Zip header fields 720 'minimal' => [IO::Compress::Base::Common::Parse_boolean, 0], 721 'zip64' => [IO::Compress::Base::Common::Parse_boolean, 0], 722 'comment' => [IO::Compress::Base::Common::Parse_any, ''], 723 'zipcomment'=> [IO::Compress::Base::Common::Parse_any, ''], 724 'name' => [IO::Compress::Base::Common::Parse_any, ''], 725 'filtername'=> [IO::Compress::Base::Common::Parse_code, undef], 726 'canonicalname'=> [IO::Compress::Base::Common::Parse_boolean, 0], 727 'efs' => [IO::Compress::Base::Common::Parse_boolean, 0], 728 'time' => [IO::Compress::Base::Common::Parse_any, undef], 729 'extime' => [IO::Compress::Base::Common::Parse_any, undef], 730 'exunix2' => [IO::Compress::Base::Common::Parse_any, undef], 731 'exunixn' => [IO::Compress::Base::Common::Parse_any, undef], 732 'extattr' => [IO::Compress::Base::Common::Parse_any, 733 $Compress::Raw::Zlib::gzip_os_code == 3 734 ? 0100644 << 16 735 : 0], 736 'os_code' => [IO::Compress::Base::Common::Parse_unsigned, $Compress::Raw::Zlib::gzip_os_code], 737 738 'textflag' => [IO::Compress::Base::Common::Parse_boolean, 0], 739 'extrafieldlocal' => [IO::Compress::Base::Common::Parse_any, undef], 740 'extrafieldcentral'=> [IO::Compress::Base::Common::Parse_any, undef], 741 'extrafieldzip64' => [IO::Compress::Base::Common::Parse_any, undef], 742 743 # Lzma 744 'preset' => [IO::Compress::Base::Common::Parse_unsigned, 6], 745 'extreme' => [IO::Compress::Base::Common::Parse_boolean, 0], 746 747 # For internal use only 748 'sparse' => [IO::Compress::Base::Common::Parse_unsigned, 0], 749 750 IO::Compress::RawDeflate::getZlibParams(), 751 defined $IO::Compress::Bzip2::VERSION 752 ? IO::Compress::Bzip2::getExtraParams() 753 : () 754 755 756 ); 757 758sub getExtraParams 759{ 760 return %PARAMS ; 761} 762 763sub getInverseClass 764{ 765 no warnings 'once'; 766 return ('IO::Uncompress::Unzip', 767 \$IO::Uncompress::Unzip::UnzipError); 768} 769 770sub getFileInfo 771{ 772 my $self = shift ; 773 my $params = shift; 774 my $filename = shift ; 775 776 if (IO::Compress::Base::Common::isaScalar($filename)) 777 { 778 $params->setValue(zip64 => 1) 779 if IO::Compress::Base::Common::isGeMax32 length (${ $filename }) ; 780 781 return ; 782 } 783 784 my ($mode, $uid, $gid, $size, $atime, $mtime, $ctime) ; 785 if ( $params->parsed('storelinks') ) 786 { 787 ($mode, $uid, $gid, $size, $atime, $mtime, $ctime) 788 = (lstat($filename))[2, 4,5,7, 8,9,10] ; 789 } 790 else 791 { 792 ($mode, $uid, $gid, $size, $atime, $mtime, $ctime) 793 = (stat($filename))[2, 4,5,7, 8,9,10] ; 794 } 795 796 $params->setValue(textflag => -T $filename ) 797 if ! $params->parsed('textflag'); 798 799 $params->setValue(zip64 => 1) 800 if IO::Compress::Base::Common::isGeMax32 $size ; 801 802 $params->setValue('name' => $filename) 803 if ! $params->parsed('name') ; 804 805 $params->setValue('time' => $mtime) 806 if ! $params->parsed('time') ; 807 808 if ( ! $params->parsed('extime')) 809 { 810 $params->setValue('mtime' => $mtime) ; 811 $params->setValue('atime' => $atime) ; 812 $params->setValue('ctime' => undef) ; # No Creation time 813 # TODO - see if can fillout creation time on non-Unix 814 } 815 816 # NOTE - Unix specific code alert 817 if (! $params->parsed('extattr')) 818 { 819 use Fcntl qw(:mode) ; 820 my $attr = $mode << 16; 821 $attr |= ZIP_A_RONLY if ($mode & S_IWRITE) == 0 ; 822 $attr |= ZIP_A_DIR if ($mode & S_IFMT ) == S_IFDIR ; 823 824 $params->setValue('extattr' => $attr); 825 } 826 827 $params->setValue('want_exunixn', [$uid, $gid]); 828 $params->setValue('uid' => $uid) ; 829 $params->setValue('gid' => $gid) ; 830 831} 832 833sub mkExtendedTime 834{ 835 # order expected is m, a, c 836 837 my $times = ''; 838 my $bit = 1 ; 839 my $flags = 0; 840 841 for my $time (@_) 842 { 843 if (defined $time) 844 { 845 $flags |= $bit; 846 $times .= pack("V", $time); 847 } 848 849 $bit <<= 1 ; 850 } 851 852 return IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_EXT_TIMESTAMP, 853 pack("C", $flags) . $times); 854} 855 856sub mkUnix2Extra 857{ 858 my $ids = ''; 859 for my $id (@_) 860 { 861 $ids .= pack("v", $id); 862 } 863 864 return IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_INFO_ZIP_UNIX2, 865 $ids); 866} 867 868sub mkUnixNExtra 869{ 870 my $uid = shift; 871 my $gid = shift; 872 873 # Assumes UID/GID are 32-bit 874 my $ids ; 875 $ids .= pack "C", 1; # version 876 $ids .= pack "C", $Config{uidsize}; 877 $ids .= pack "V", $uid; 878 $ids .= pack "C", $Config{gidsize}; 879 $ids .= pack "V", $gid; 880 881 return IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_INFO_ZIP_UNIXN, 882 $ids); 883} 884 885 886# from Archive::Zip 887sub _unixToDosTime # Archive::Zip::Member 888{ 889 my $time_t = shift; 890 891 # TODO - add something to cope with unix time < 1980 892 my ( $sec, $min, $hour, $mday, $mon, $year ) = localtime($time_t); 893 my $dt = 0; 894 $dt += ( $sec >> 1 ); 895 $dt += ( $min << 5 ); 896 $dt += ( $hour << 11 ); 897 $dt += ( $mday << 16 ); 898 $dt += ( ( $mon + 1 ) << 21 ); 899 $dt += ( ( $year - 80 ) << 25 ); 900 return $dt; 901} 902 9031; 904 905__END__ 906 907=head1 NAME 908 909IO::Compress::Zip - Write zip files/buffers 910 911=head1 SYNOPSIS 912 913 use IO::Compress::Zip qw(zip $ZipError) ; 914 915 my $status = zip $input => $output [,OPTS] 916 or die "zip failed: $ZipError\n"; 917 918 my $z = IO::Compress::Zip->new( $output [,OPTS] ) 919 or die "zip failed: $ZipError\n"; 920 921 $z->print($string); 922 $z->printf($format, $string); 923 $z->write($string); 924 $z->syswrite($string [, $length, $offset]); 925 $z->flush(); 926 $z->tell(); 927 $z->eof(); 928 $z->seek($position, $whence); 929 $z->binmode(); 930 $z->fileno(); 931 $z->opened(); 932 $z->autoflush(); 933 $z->input_line_number(); 934 $z->newStream( [OPTS] ); 935 936 $z->deflateParams(); 937 938 $z->close() ; 939 940 $ZipError ; 941 942 # IO::File mode 943 944 print $z $string; 945 printf $z $format, $string; 946 tell $z 947 eof $z 948 seek $z, $position, $whence 949 binmode $z 950 fileno $z 951 close $z ; 952 953=head1 DESCRIPTION 954 955This module provides a Perl interface that allows writing zip 956compressed data to files or buffer. 957 958The primary purpose of this module is to provide streaming write access to 959zip files and buffers. 960 961At present the following compression methods are supported by IO::Compress::Zip 962 963=over 5 964 965=item Store (0) 966 967=item Deflate (8) 968 969=item Bzip2 (12) 970 971To write Bzip2 content, the module C<IO::Uncompress::Bunzip2> must 972be installed. 973 974=item Lzma (14) 975 976To write LZMA content, the module C<IO::Uncompress::UnLzma> must 977be installed. 978 979=item Zstandard (93) 980 981To write Zstandard content, the module C<IO::Compress::Zstd> must 982be installed. 983 984=item Xz (95) 985 986To write Xz content, the module C<IO::Uncompress::UnXz> must 987be installed. 988 989=back 990 991For reading zip files/buffers, see the companion module 992L<IO::Uncompress::Unzip|IO::Uncompress::Unzip>. 993 994=head1 Functional Interface 995 996A top-level function, C<zip>, is provided to carry out 997"one-shot" compression between buffers and/or files. For finer 998control over the compression process, see the L</"OO Interface"> 999section. 1000 1001 use IO::Compress::Zip qw(zip $ZipError) ; 1002 1003 zip $input_filename_or_reference => $output_filename_or_reference [,OPTS] 1004 or die "zip failed: $ZipError\n"; 1005 1006The functional interface needs Perl5.005 or better. 1007 1008=head2 zip $input_filename_or_reference => $output_filename_or_reference [, OPTS] 1009 1010C<zip> expects at least two parameters, 1011C<$input_filename_or_reference> and C<$output_filename_or_reference> 1012and zero or more optional parameters (see L</Optional Parameters>) 1013 1014=head3 The C<$input_filename_or_reference> parameter 1015 1016The parameter, C<$input_filename_or_reference>, is used to define the 1017source of the uncompressed data. 1018 1019It can take one of the following forms: 1020 1021=over 5 1022 1023=item A filename 1024 1025If the C<$input_filename_or_reference> parameter is a simple scalar, it is 1026assumed to be a filename. This file will be opened for reading and the 1027input data will be read from it. 1028 1029=item A filehandle 1030 1031If the C<$input_filename_or_reference> parameter is a filehandle, the input 1032data will be read from it. The string '-' can be used as an alias for 1033standard input. 1034 1035=item A scalar reference 1036 1037If C<$input_filename_or_reference> is a scalar reference, the input data 1038will be read from C<$$input_filename_or_reference>. 1039 1040=item An array reference 1041 1042If C<$input_filename_or_reference> is an array reference, each element in 1043the array must be a filename. 1044 1045The input data will be read from each file in turn. 1046 1047The complete array will be walked to ensure that it only 1048contains valid filenames before any data is compressed. 1049 1050=item An Input FileGlob string 1051 1052If C<$input_filename_or_reference> is a string that is delimited by the 1053characters "<" and ">" C<zip> will assume that it is an 1054I<input fileglob string>. The input is the list of files that match the 1055fileglob. 1056 1057See L<File::GlobMapper|File::GlobMapper> for more details. 1058 1059=back 1060 1061If the C<$input_filename_or_reference> parameter is any other type, 1062C<undef> will be returned. 1063 1064In addition, if C<$input_filename_or_reference> corresponds to a filename 1065from the filesystem, a number of zip file header fields will be populated by default 1066using the following attributes from the input file 1067 1068=over 5 1069 1070=item * the full filename contained in C<$input_filename_or_reference> 1071 1072=item * the file protection attributes 1073 1074=item * the UID/GID for the file 1075 1076=item * the file timestamps 1077 1078=back 1079 1080If you do not want to use these defaults they can be overridden by 1081explicitly setting one, or more, of the C<Name>, C<Time>, C<TextFlag>, C<ExtAttr>, C<exUnixN> and C<exTime> options or by setting the 1082C<Minimal> parameter. 1083 1084=head3 The C<$output_filename_or_reference> parameter 1085 1086The parameter C<$output_filename_or_reference> is used to control the 1087destination of the compressed data. This parameter can take one of 1088these forms. 1089 1090=over 5 1091 1092=item A filename 1093 1094If the C<$output_filename_or_reference> parameter is a simple scalar, it is 1095assumed to be a filename. This file will be opened for writing and the 1096compressed data will be written to it. 1097 1098=item A filehandle 1099 1100If the C<$output_filename_or_reference> parameter is a filehandle, the 1101compressed data will be written to it. The string '-' can be used as 1102an alias for standard output. 1103 1104=item A scalar reference 1105 1106If C<$output_filename_or_reference> is a scalar reference, the 1107compressed data will be stored in C<$$output_filename_or_reference>. 1108 1109=item An Array Reference 1110 1111If C<$output_filename_or_reference> is an array reference, 1112the compressed data will be pushed onto the array. 1113 1114=item An Output FileGlob 1115 1116If C<$output_filename_or_reference> is a string that is delimited by the 1117characters "<" and ">" C<zip> will assume that it is an 1118I<output fileglob string>. The output is the list of files that match the 1119fileglob. 1120 1121When C<$output_filename_or_reference> is an fileglob string, 1122C<$input_filename_or_reference> must also be a fileglob string. Anything 1123else is an error. 1124 1125See L<File::GlobMapper|File::GlobMapper> for more details. 1126 1127=back 1128 1129If the C<$output_filename_or_reference> parameter is any other type, 1130C<undef> will be returned. 1131 1132=head2 Notes 1133 1134When C<$input_filename_or_reference> maps to multiple files/buffers and 1135C<$output_filename_or_reference> is a single 1136file/buffer the input files/buffers will each be stored 1137in C<$output_filename_or_reference> as a distinct entry. 1138 1139=head2 Optional Parameters 1140 1141The optional parameters for the one-shot function C<zip> 1142are (for the most part) identical to those used with the OO interface defined in the 1143L</"Constructor Options"> section. The exceptions are listed below 1144 1145=over 5 1146 1147=item C<< AutoClose => 0|1 >> 1148 1149This option applies to any input or output data streams to 1150C<zip> that are filehandles. 1151 1152If C<AutoClose> is specified, and the value is true, it will result in all 1153input and/or output filehandles being closed once C<zip> has 1154completed. 1155 1156This parameter defaults to 0. 1157 1158=item C<< BinModeIn => 0|1 >> 1159 1160This option is now a no-op. All files will be read in binmode. 1161 1162=item C<< Append => 0|1 >> 1163 1164The behaviour of this option is dependent on the type of output data 1165stream. 1166 1167=over 5 1168 1169=item * A Buffer 1170 1171If C<Append> is enabled, all compressed data will be append to the end of 1172the output buffer. Otherwise the output buffer will be cleared before any 1173compressed data is written to it. 1174 1175=item * A Filename 1176 1177If C<Append> is enabled, the file will be opened in append mode. Otherwise 1178the contents of the file, if any, will be truncated before any compressed 1179data is written to it. 1180 1181=item * A Filehandle 1182 1183If C<Append> is enabled, the filehandle will be positioned to the end of 1184the file via a call to C<seek> before any compressed data is 1185written to it. Otherwise the file pointer will not be moved. 1186 1187=back 1188 1189When C<Append> is specified, and set to true, it will I<append> all compressed 1190data to the output data stream. 1191 1192So when the output is a filehandle it will carry out a seek to the eof 1193before writing any compressed data. If the output is a filename, it will be opened for 1194appending. If the output is a buffer, all compressed data will be 1195appended to the existing buffer. 1196 1197Conversely when C<Append> is not specified, or it is present and is set to 1198false, it will operate as follows. 1199 1200When the output is a filename, it will truncate the contents of the file 1201before writing any compressed data. If the output is a filehandle 1202its position will not be changed. If the output is a buffer, it will be 1203wiped before any compressed data is output. 1204 1205Defaults to 0. 1206 1207=back 1208 1209=head2 Oneshot Examples 1210 1211Here are a few example that show the capabilities of the module. 1212 1213=head3 Streaming 1214 1215This very simple command line example demonstrates the streaming capabilities of the module. 1216The code reads data from STDIN, compresses it, and writes the compressed data to STDOUT. 1217 1218 $ echo hello world | perl -MIO::Compress::Zip=zip -e 'zip \*STDIN => \*STDOUT' >output.zip 1219 1220The special filename "-" can be used as a standin for both C<\*STDIN> and C<\*STDOUT>, 1221so the above can be rewritten as 1222 1223 $ echo hello world | perl -MIO::Compress::Zip=zip -e 'zip "-" => "-"' >output.zip 1224 1225One problem with creating a zip archive directly from STDIN can be demonstrated by looking at 1226the contents of the zip file, output.zip, that we have just created. 1227 1228 $ unzip -l output.zip 1229 Archive: output.zip 1230 Length Date Time Name 1231 --------- ---------- ----- ---- 1232 12 2019-08-16 22:21 1233 --------- ------- 1234 12 1 file 1235 1236The archive member (filename) used is the empty string. 1237 1238If that doesn't suit your needs, you can explicitly set the filename used 1239in the zip archive by specifying the L<Name|"File Naming Options"> option, like so 1240 1241 echo hello world | perl -MIO::Compress::Zip=zip -e 'zip "-" => "-", Name => "hello.txt"' >output.zip 1242 1243Now the contents of the zip file looks like this 1244 1245 $ unzip -l output.zip 1246 Archive: output.zip 1247 Length Date Time Name 1248 --------- ---------- ----- ---- 1249 12 2019-08-16 22:22 hello.txt 1250 --------- ------- 1251 12 1 file 1252 1253=head3 Compressing a file from the filesystem 1254 1255To read the contents of the file C<file1.txt> and write the compressed 1256data to the file C<file1.txt.zip>. 1257 1258 use strict ; 1259 use warnings ; 1260 use IO::Compress::Zip qw(zip $ZipError) ; 1261 1262 my $input = "file1.txt"; 1263 zip $input => "$input.zip" 1264 or die "zip failed: $ZipError\n"; 1265 1266=head3 Reading from a Filehandle and writing to an in-memory buffer 1267 1268To read from an existing Perl filehandle, C<$input>, and write the 1269compressed data to a buffer, C<$buffer>. 1270 1271 use strict ; 1272 use warnings ; 1273 use IO::Compress::Zip qw(zip $ZipError) ; 1274 use IO::File ; 1275 1276 my $input = IO::File->new( "<file1.txt" ) 1277 or die "Cannot open 'file1.txt': $!\n" ; 1278 my $buffer ; 1279 zip $input => \$buffer 1280 or die "zip failed: $ZipError\n"; 1281 1282=head3 Compressing multiple files 1283 1284To create a zip file, C<output.zip>, that contains the compressed contents 1285of the files C<alpha.txt> and C<beta.txt> 1286 1287 use strict ; 1288 use warnings ; 1289 use IO::Compress::Zip qw(zip $ZipError) ; 1290 1291 zip [ 'alpha.txt', 'beta.txt' ] => 'output.zip' 1292 or die "zip failed: $ZipError\n"; 1293 1294Alternatively, rather than having to explicitly name each of the files that 1295you want to compress, you could use a fileglob to select all the C<txt> 1296files in the current directory, as follows 1297 1298 use strict ; 1299 use warnings ; 1300 use IO::Compress::Zip qw(zip $ZipError) ; 1301 1302 my @files = <*.txt>; 1303 zip \@files => 'output.zip' 1304 or die "zip failed: $ZipError\n"; 1305 1306or more succinctly 1307 1308 zip [ <*.txt> ] => 'output.zip' 1309 or die "zip failed: $ZipError\n"; 1310 1311=head1 OO Interface 1312 1313=head2 Constructor 1314 1315The format of the constructor for C<IO::Compress::Zip> is shown below 1316 1317 my $z = IO::Compress::Zip->new( $output [,OPTS] ) 1318 or die "IO::Compress::Zip failed: $ZipError\n"; 1319 1320The constructor takes one mandatory parameter, C<$output>, defined below and 1321zero or more C<OPTS>, defined in L<Constructor Options>. 1322 1323It returns an C<IO::Compress::Zip> object on success and C<undef> on failure. 1324The variable C<$ZipError> will contain an error message on failure. 1325 1326If you are running Perl 5.005 or better the object, C<$z>, returned from 1327IO::Compress::Zip can be used exactly like an L<IO::File|IO::File> filehandle. 1328This means that all normal output file operations can be carried out 1329with C<$z>. 1330For example, to write to a compressed file/buffer you can use either of 1331these forms 1332 1333 $z->print("hello world\n"); 1334 print $z "hello world\n"; 1335 1336Below is a simple exaple of using the OO interface to create an output file 1337C<myfile.zip> and write some data to it. 1338 1339 my $filename = "myfile.zip"; 1340 my $z = IO::Compress::Zip->new($filename) 1341 or die "IO::Compress::Zip failed: $ZipError\n"; 1342 1343 $z->print("abcde"); 1344 $z->close(); 1345 1346See the L</Examples> for more. 1347 1348The mandatory parameter C<$output> is used to control the destination 1349of the compressed data. This parameter can take one of these forms. 1350 1351=over 5 1352 1353=item A filename 1354 1355If the C<$output> parameter is a simple scalar, it is assumed to be a 1356filename. This file will be opened for writing and the compressed data 1357will be written to it. 1358 1359=item A filehandle 1360 1361If the C<$output> parameter is a filehandle, the compressed data will be 1362written to it. 1363The string '-' can be used as an alias for standard output. 1364 1365=item A scalar reference 1366 1367If C<$output> is a scalar reference, the compressed data will be stored 1368in C<$$output>. 1369 1370=back 1371 1372If the C<$output> parameter is any other type, C<IO::Compress::Zip>::new will 1373return undef. 1374 1375=head2 Constructor Options 1376 1377C<OPTS> is any combination of zero or more the following options: 1378 1379=over 5 1380 1381=item C<< AutoClose => 0|1 >> 1382 1383This option is only valid when the C<$output> parameter is a filehandle. If 1384specified, and the value is true, it will result in the C<$output> being 1385closed once either the C<close> method is called or the C<IO::Compress::Zip> 1386object is destroyed. 1387 1388This parameter defaults to 0. 1389 1390=item C<< Append => 0|1 >> 1391 1392Opens C<$output> in append mode. 1393 1394The behaviour of this option is dependent on the type of C<$output>. 1395 1396=over 5 1397 1398=item * A Buffer 1399 1400If C<$output> is a buffer and C<Append> is enabled, all compressed data 1401will be append to the end of C<$output>. Otherwise C<$output> will be 1402cleared before any data is written to it. 1403 1404=item * A Filename 1405 1406If C<$output> is a filename and C<Append> is enabled, the file will be 1407opened in append mode. Otherwise the contents of the file, if any, will be 1408truncated before any compressed data is written to it. 1409 1410=item * A Filehandle 1411 1412If C<$output> is a filehandle, the file pointer will be positioned to the 1413end of the file via a call to C<seek> before any compressed data is written 1414to it. Otherwise the file pointer will not be moved. 1415 1416=back 1417 1418This parameter defaults to 0. 1419 1420=back 1421 1422=head3 File Naming Options 1423 1424A quick bit of zip file terminology -- A zip archive consists of one or more I<archive members>, where each member has an associated 1425filename, known as the I<archive member name>. 1426 1427The options listed in this section control how the I<archive member name> (or filename) is stored the zip archive. 1428 1429=over 5 1430 1431=item C<< Name => $string >> 1432 1433This option is used to explicitly set the I<archive member name> in 1434the zip archive to C<$string>. 1435Most of the time you don't need to make use of this option. 1436By default when adding a filename to the zip archive, the I<archive member name> will match the filename. 1437 1438You should only need to use this option if you want the I<archive member name> 1439to be different from the uncompressed filename or when the input is a filehandle or a buffer. 1440 1441The default behaviour for what I<archive member name> is used when the C<Name> option 1442is I<not> specified depends on the form of the C<$input> parameter: 1443 1444=over 5 1445 1446=item * 1447 1448If the C<$input> parameter is a filename, the 1449value of C<$input> will be used for the I<archive member name> . 1450 1451=item * 1452If the C<$input> parameter is not a filename, 1453the I<archive member name> will be an empty string. 1454 1455=back 1456 1457Note that both the C<CanonicalName> and C<FilterName> options 1458can modify the value used for the I<archive member name>. 1459 1460Also note that you should set the C<Efs> option to true if you are working 1461with UTF8 filenames. 1462 1463=item C<< CanonicalName => 0|1 >> 1464 1465This option controls whether the I<archive member name> is 1466I<normalized> into Unix format before being written to the zip file. 1467 1468It is recommended that you enable this option unless you really need 1469to create a non-standard Zip file. 1470 1471This is what APPNOTE.TXT has to say on what should be stored in the zip 1472filename header field. 1473 1474 The name of the file, with optional relative path. 1475 The path stored should not contain a drive or 1476 device letter, or a leading slash. All slashes 1477 should be forward slashes '/' as opposed to 1478 backwards slashes '\' for compatibility with Amiga 1479 and UNIX file systems etc. 1480 1481This option defaults to B<false>. 1482 1483=item C<< FilterName => sub { ... } >> 1484 1485This option allow the I<archive member> name to be modified 1486before it is written to the zip file. 1487 1488This option takes a parameter that must be a reference to a sub. On entry 1489to the sub the C<$_> variable will contain the name to be filtered. If no 1490filename is available C<$_> will contain an empty string. 1491 1492The value of C<$_> when the sub returns will be used as the I<archive member name>. 1493 1494Note that if C<CanonicalName> is enabled, a 1495normalized filename will be passed to the sub. 1496 1497If you use C<FilterName> to modify the filename, it is your responsibility 1498to keep the filename in Unix format. 1499 1500Although this option can be used with the OO interface, it is of most use 1501with the one-shot interface. For example, the code below shows how 1502C<FilterName> can be used to remove the path component from a series of 1503filenames before they are stored in C<$zipfile>. 1504 1505 sub compressTxtFiles 1506 { 1507 my $zipfile = shift ; 1508 my $dir = shift ; 1509 1510 zip [ <$dir/*.txt> ] => $zipfile, 1511 FilterName => sub { s[^$dir/][] } ; 1512 } 1513 1514=item C<< Efs => 0|1 >> 1515 1516This option controls setting of the "Language Encoding Flag" (EFS) in the zip 1517archive. When set, the filename and comment fields for the zip archive MUST 1518be valid UTF-8. 1519 1520If the string used for the filename and/or comment is not valid UTF-8 when this option 1521is true, the script will die with a "wide character" error. 1522 1523Note that this option only works with Perl 5.8.4 or better. 1524 1525This option defaults to B<false>. 1526 1527=back 1528 1529=head3 Overall Zip Archive Structure 1530 1531=over 5 1532 1533=item C<< Minimal => 1|0 >> 1534 1535If specified, this option will disable the creation of all extra fields 1536in the zip local and central headers. So the C<exTime>, C<exUnix2>, 1537C<exUnixN>, C<ExtraFieldLocal> and C<ExtraFieldCentral> options will 1538be ignored. 1539 1540This parameter defaults to 0. 1541 1542=item C<< Stream => 0|1 >> 1543 1544This option controls whether the zip file/buffer output is created in 1545streaming mode. 1546 1547Note that when outputting to a file with streaming mode disabled (C<Stream> 1548is 0), the output file must be seekable. 1549 1550The default is 1. 1551 1552=item C<< Zip64 => 0|1 >> 1553 1554Create a Zip64 zip file/buffer. This option is used if you want 1555to store files larger than 4 Gig or store more than 64K files in a single 1556zip archive. 1557 1558C<Zip64> will be automatically set, as needed, if working with the one-shot 1559interface when the input is either a filename or a scalar reference. 1560 1561If you intend to manipulate the Zip64 zip files created with this module 1562using an external zip/unzip, make sure that it supports Zip64. 1563 1564In particular, if you are using Info-Zip you need to have zip version 3.x 1565or better to update a Zip64 archive and unzip version 6.x to read a zip64 1566archive. 1567 1568The default is 0. 1569 1570=back 1571 1572=head3 Deflate Compression Options 1573 1574=over 5 1575 1576=item -Level 1577 1578Defines the compression level used by zlib. The value should either be 1579a number between 0 and 9 (0 means no compression and 9 is maximum 1580compression), or one of the symbolic constants defined below. 1581 1582 Z_NO_COMPRESSION 1583 Z_BEST_SPEED 1584 Z_BEST_COMPRESSION 1585 Z_DEFAULT_COMPRESSION 1586 1587The default is Z_DEFAULT_COMPRESSION. 1588 1589Note, these constants are not imported by C<IO::Compress::Zip> by default. 1590 1591 use IO::Compress::Zip qw(:strategy); 1592 use IO::Compress::Zip qw(:constants); 1593 use IO::Compress::Zip qw(:all); 1594 1595=item -Strategy 1596 1597Defines the strategy used to tune the compression. Use one of the symbolic 1598constants defined below. 1599 1600 Z_FILTERED 1601 Z_HUFFMAN_ONLY 1602 Z_RLE 1603 Z_FIXED 1604 Z_DEFAULT_STRATEGY 1605 1606The default is Z_DEFAULT_STRATEGY. 1607 1608=back 1609 1610=head3 Bzip2 Compression Options 1611 1612=over 5 1613 1614=item C<< BlockSize100K => number >> 1615 1616Specify the number of 100K blocks bzip2 uses during compression. 1617 1618Valid values are from 1 to 9, where 9 is best compression. 1619 1620This option is only valid if the C<Method> is ZIP_CM_BZIP2. It is ignored 1621otherwise. 1622 1623The default is 1. 1624 1625=item C<< WorkFactor => number >> 1626 1627Specifies how much effort bzip2 should take before resorting to a slower 1628fallback compression algorithm. 1629 1630Valid values range from 0 to 250, where 0 means use the default value 30. 1631 1632This option is only valid if the C<Method> is ZIP_CM_BZIP2. It is ignored 1633otherwise. 1634 1635The default is 0. 1636 1637=back 1638 1639=head3 Lzma and Xz Compression Options 1640 1641=over 5 1642 1643=item C<< Preset => number >> 1644 1645Used to choose the LZMA compression preset. 1646 1647Valid values are 0-9 and C<LZMA_PRESET_DEFAULT>. 1648 16490 is the fastest compression with the lowest memory usage and the lowest 1650compression. 1651 16529 is the slowest compression with the highest memory usage but with the best 1653compression. 1654 1655This option is only valid if the C<Method> is ZIP_CM_LZMA. It is ignored 1656otherwise. 1657 1658Defaults to C<LZMA_PRESET_DEFAULT> (6). 1659 1660=item C<< Extreme => 0|1 >> 1661 1662Makes LZMA compression a lot slower, but a small compression gain. 1663 1664This option is only valid if the C<Method> is ZIP_CM_LZMA. It is ignored 1665otherwise. 1666 1667Defaults to 0. 1668 1669=back 1670 1671=head3 Other Options 1672 1673=over 5 1674 1675=item C<< Time => $number >> 1676 1677Sets the last modified time field in the zip header to $number. 1678 1679This field defaults to the time the C<IO::Compress::Zip> object was created 1680if this option is not specified and the C<$input> parameter is not a 1681filename. 1682 1683=item C<< ExtAttr => $attr >> 1684 1685This option controls the "external file attributes" field in the central 1686header of the zip file. This is a 4 byte field. 1687 1688If you are running a Unix derivative this value defaults to 1689 1690 0100644 << 16 1691 1692This should allow read/write access to any files that are extracted from 1693the zip file/buffer`. 1694 1695For all other systems it defaults to 0. 1696 1697=item C<< exTime => [$atime, $mtime, $ctime] >> 1698 1699This option expects an array reference with exactly three elements: 1700C<$atime>, C<mtime> and C<$ctime>. These correspond to the last access 1701time, last modification time and creation time respectively. 1702 1703It uses these values to set the extended timestamp field (ID is "UT") in 1704the local zip header using the three values, $atime, $mtime, $ctime. In 1705addition it sets the extended timestamp field in the central zip header 1706using C<$mtime>. 1707 1708If any of the three values is C<undef> that time value will not be used. 1709So, for example, to set only the C<$mtime> you would use this 1710 1711 exTime => [undef, $mtime, undef] 1712 1713If the C<Minimal> option is set to true, this option will be ignored. 1714 1715By default no extended time field is created. 1716 1717=item C<< exUnix2 => [$uid, $gid] >> 1718 1719This option expects an array reference with exactly two elements: C<$uid> 1720and C<$gid>. These values correspond to the numeric User ID (UID) and Group ID 1721(GID) of the owner of the files respectively. 1722 1723When the C<exUnix2> option is present it will trigger the creation of a 1724Unix2 extra field (ID is "Ux") in the local zip header. This will be populated 1725with C<$uid> and C<$gid>. An empty Unix2 extra field will also 1726be created in the central zip header. 1727 1728Note - The UID & GID are stored as 16-bit 1729integers in the "Ux" field. Use C<< exUnixN >> if your UID or GID are 173032-bit. 1731 1732If the C<Minimal> option is set to true, this option will be ignored. 1733 1734By default no Unix2 extra field is created. 1735 1736=item C<< exUnixN => [$uid, $gid] >> 1737 1738This option expects an array reference with exactly two elements: C<$uid> 1739and C<$gid>. These values correspond to the numeric User ID (UID) and Group ID 1740(GID) of the owner of the files respectively. 1741 1742When the C<exUnixN> option is present it will trigger the creation of a 1743UnixN extra field (ID is "ux") in both the local and central zip headers. 1744This will be populated with C<$uid> and C<$gid>. 1745The UID & GID are stored as 32-bit integers. 1746 1747If the C<Minimal> option is set to true, this option will be ignored. 1748 1749By default no UnixN extra field is created. 1750 1751=item C<< Comment => $comment >> 1752 1753Stores the contents of C<$comment> in the Central File Header of 1754the zip file. 1755 1756Set the C<Efs> option to true if you want to store a UTF8 comment. 1757 1758By default, no comment field is written to the zip file. 1759 1760=item C<< ZipComment => $comment >> 1761 1762Stores the contents of C<$comment> in the End of Central Directory record 1763of the zip file. 1764 1765By default, no comment field is written to the zip file. 1766 1767=item C<< Method => $method >> 1768 1769Controls which compression method is used. At present the compression 1770methods supported are: Store (no compression at all), Deflate, 1771Bzip2, Zstd, Xz and Lzma. 1772 1773The symbols ZIP_CM_STORE, ZIP_CM_DEFLATE, ZIP_CM_BZIP2, ZIP_CM_ZSTD, ZIP_CM_XZ and ZIP_CM_LZMA 1774are used to select the compression method. 1775 1776These constants are not imported by C<IO::Compress::Zip> by default. 1777 1778 use IO::Compress::Zip qw(:zip_method); 1779 use IO::Compress::Zip qw(:constants); 1780 use IO::Compress::Zip qw(:all); 1781 1782Note that to create Bzip2 content, the module C<IO::Compress::Bzip2> must 1783be installed. A fatal error will be thrown if you attempt to create Bzip2 1784content when C<IO::Compress::Bzip2> is not available. 1785 1786Note that to create Lzma content, the module C<IO::Compress::Lzma> must 1787be installed. A fatal error will be thrown if you attempt to create Lzma 1788content when C<IO::Compress::Lzma> is not available. 1789 1790Note that to create Xz content, the module C<IO::Compress::Xz> must 1791be installed. A fatal error will be thrown if you attempt to create Xz 1792content when C<IO::Compress::Xz> is not available. 1793 1794Note that to create Zstd content, the module C<IO::Compress::Zstd> must 1795be installed. A fatal error will be thrown if you attempt to create Zstd 1796content when C<IO::Compress::Zstd> is not available. 1797 1798The default method is ZIP_CM_DEFLATE. 1799 1800=item C<< TextFlag => 0|1 >> 1801 1802This parameter controls the setting of a bit in the zip central header. It 1803is used to signal that the data stored in the zip file/buffer is probably 1804text. 1805 1806In one-shot mode this flag will be set to true if the Perl C<-T> operator thinks 1807the file contains text. 1808 1809The default is 0. 1810 1811=item C<< ExtraFieldLocal => $data >> 1812 1813=item C<< ExtraFieldCentral => $data >> 1814 1815The C<ExtraFieldLocal> option is used to store additional metadata in the 1816local header for the zip file/buffer. The C<ExtraFieldCentral> does the 1817same for the matching central header. 1818 1819An extra field consists of zero or more subfields. Each subfield consists 1820of a two byte header followed by the subfield data. 1821 1822The list of subfields can be supplied in any of the following formats 1823 1824 ExtraFieldLocal => [$id1, $data1, 1825 $id2, $data2, 1826 ... 1827 ] 1828 1829 ExtraFieldLocal => [ [$id1 => $data1], 1830 [$id2 => $data2], 1831 ... 1832 ] 1833 1834 ExtraFieldLocal => { $id1 => $data1, 1835 $id2 => $data2, 1836 ... 1837 } 1838 1839Where C<$id1>, C<$id2> are two byte subfield ID's. 1840 1841If you use the hash syntax, you have no control over the order in which 1842the ExtraSubFields are stored, plus you cannot have SubFields with 1843duplicate ID. 1844 1845Alternatively the list of subfields can by supplied as a scalar, thus 1846 1847 ExtraField => $rawdata 1848 1849In this case C<IO::Compress::Zip> will check that C<$rawdata> consists of 1850zero or more conformant sub-fields. 1851 1852The Extended Time field (ID "UT"), set using the C<exTime> option, and the 1853Unix2 extra field (ID "Ux), set using the C<exUnix2> option, are examples 1854of extra fields. 1855 1856If the C<Minimal> option is set to true, this option will be ignored. 1857 1858The maximum size of an extra field 65535 bytes. 1859 1860=item C<< Strict => 0|1 >> 1861 1862This is a placeholder option. 1863 1864=back 1865 1866=head2 Examples 1867 1868=head3 Streaming 1869 1870This very simple command line example demonstrates the streaming capabilities 1871of the module. The code reads data from STDIN or all the files given on the 1872commandline, compresses it, and writes the compressed data to STDOUT. 1873 1874 use strict ; 1875 use warnings ; 1876 use IO::Compress::Zip qw(zip $ZipError) ; 1877 1878 my $z = IO::Compress::Zip->new("-", Stream => 1) 1879 or die "IO::Compress::Zip failed: $ZipError\n"; 1880 1881 while (<>) { 1882 $z->print("abcde"); 1883 } 1884 $z->close(); 1885 1886Note the use of C<"-"> to means C<STDOUT>. Alternatively you can use C<\*STDOUT>. 1887 1888One problem with creating a zip archive directly from STDIN can be demonstrated by looking at 1889the contents of the zip file, output.zip, that we have just created 1890(assumg you have redirected it to a file called C<output.zip>). 1891 1892 $ unzip -l output.zip 1893 Archive: output.zip 1894 Length Date Time Name 1895 --------- ---------- ----- ---- 1896 12 2019-08-16 22:21 1897 --------- ------- 1898 12 1 file 1899 1900The archive member (filename) used is the empty string. 1901 1902If that doesn't suit your needs, you can explicitly set the filename used 1903in the zip archive by specifying the L<Name|"File Naming Options"> option, like so 1904 1905 my $z = IO::Compress::Zip->new("-", Name => "hello.txt", Stream => 1) 1906 1907Now the contents of the zip file looks like this 1908 1909 $ unzip -l output.zip 1910 Archive: output.zip 1911 Length Date Time Name 1912 --------- ---------- ----- ---- 1913 12 2019-08-16 22:22 hello.txt 1914 --------- ------- 1915 12 1 file 1916 1917=head3 Compressing a file from the filesystem 1918 1919To read the contents of the file C<file1.txt> and write the compressed 1920data to the file C<file1.txt.zip> there are a few options 1921 1922Start by creating the compression object and opening the input file 1923 1924 use strict ; 1925 use warnings ; 1926 use IO::Compress::Zip qw(zip $ZipError) ; 1927 1928 my $input = "file1.txt"; 1929 my $z = IO::Compress::Zip->new("file1.txt.zip") 1930 or die "IO::Compress::Zip failed: $ZipError\n"; 1931 1932 # open the input file 1933 open my $fh, "<", "file1.txt" 1934 or die "Cannot open file1.txt: $!\n"; 1935 1936 # loop through the input file & write to the compressed file 1937 while (<$fh>) { 1938 $z->print($_); 1939 } 1940 1941 # not forgetting to close the compressed file 1942 $z->close(); 1943 1944=head3 Compressing multiple files 1945 1946To create a zip file, C<output.zip>, that contains the compressed contents 1947of the files C<alpha.txt> and C<beta.txt> 1948 1949 use strict ; 1950 use warnings ; 1951 use IO::Compress::Zip qw(zip $ZipError) ; 1952 1953 my $z = IO::Compress::Zip->new("output.zip", Name => "alpha.txt") 1954 or die "IO::Compress::Zip failed: $ZipError\n"; 1955 1956 # open the input file 1957 open my $fh, "<", "file1.txt" 1958 or die "Cannot open file1.txt: $!\n"; 1959 1960 # loop through the input file & write to the compressed file 1961 while (<$fh>) { 1962 $z->print($_); 1963 } 1964 1965 # move to next file 1966 $z->newStream(Name => "beta.txt") 1967 1968 while (<$fh>) { 1969 $z->print($_); 1970 } 1971 1972 $z->close(); 1973 1974=head1 Methods 1975 1976=head2 print 1977 1978Usage is 1979 1980 $z->print($data) 1981 print $z $data 1982 1983Compresses and outputs the contents of the C<$data> parameter. This 1984has the same behaviour as the C<print> built-in. 1985 1986Returns true if successful. 1987 1988=head2 printf 1989 1990Usage is 1991 1992 $z->printf($format, $data) 1993 printf $z $format, $data 1994 1995Compresses and outputs the contents of the C<$data> parameter. 1996 1997Returns true if successful. 1998 1999=head2 syswrite 2000 2001Usage is 2002 2003 $z->syswrite $data 2004 $z->syswrite $data, $length 2005 $z->syswrite $data, $length, $offset 2006 2007Compresses and outputs the contents of the C<$data> parameter. 2008 2009Returns the number of uncompressed bytes written, or C<undef> if 2010unsuccessful. 2011 2012=head2 write 2013 2014Usage is 2015 2016 $z->write $data 2017 $z->write $data, $length 2018 $z->write $data, $length, $offset 2019 2020Compresses and outputs the contents of the C<$data> parameter. 2021 2022Returns the number of uncompressed bytes written, or C<undef> if 2023unsuccessful. 2024 2025=head2 flush 2026 2027Usage is 2028 2029 $z->flush; 2030 $z->flush($flush_type); 2031 2032Flushes any pending compressed data to the output file/buffer. 2033 2034This method takes an optional parameter, C<$flush_type>, that controls 2035how the flushing will be carried out. By default the C<$flush_type> 2036used is C<Z_FINISH>. Other valid values for C<$flush_type> are 2037C<Z_NO_FLUSH>, C<Z_SYNC_FLUSH>, C<Z_FULL_FLUSH> and C<Z_BLOCK>. It is 2038strongly recommended that you only set the C<flush_type> parameter if 2039you fully understand the implications of what it does - overuse of C<flush> 2040can seriously degrade the level of compression achieved. See the C<zlib> 2041documentation for details. 2042 2043Returns true on success. 2044 2045=head2 tell 2046 2047Usage is 2048 2049 $z->tell() 2050 tell $z 2051 2052Returns the uncompressed file offset. 2053 2054=head2 eof 2055 2056Usage is 2057 2058 $z->eof(); 2059 eof($z); 2060 2061Returns true if the C<close> method has been called. 2062 2063=head2 seek 2064 2065 $z->seek($position, $whence); 2066 seek($z, $position, $whence); 2067 2068Provides a sub-set of the C<seek> functionality, with the restriction 2069that it is only legal to seek forward in the output file/buffer. 2070It is a fatal error to attempt to seek backward. 2071 2072Empty parts of the file/buffer will have NULL (0x00) bytes written to them. 2073 2074The C<$whence> parameter takes one the usual values, namely SEEK_SET, 2075SEEK_CUR or SEEK_END. 2076 2077Returns 1 on success, 0 on failure. 2078 2079=head2 binmode 2080 2081Usage is 2082 2083 $z->binmode 2084 binmode $z ; 2085 2086This is a noop provided for completeness. 2087 2088=head2 opened 2089 2090 $z->opened() 2091 2092Returns true if the object currently refers to a opened file/buffer. 2093 2094=head2 autoflush 2095 2096 my $prev = $z->autoflush() 2097 my $prev = $z->autoflush(EXPR) 2098 2099If the C<$z> object is associated with a file or a filehandle, this method 2100returns the current autoflush setting for the underlying filehandle. If 2101C<EXPR> is present, and is non-zero, it will enable flushing after every 2102write/print operation. 2103 2104If C<$z> is associated with a buffer, this method has no effect and always 2105returns C<undef>. 2106 2107B<Note> that the special variable C<$|> B<cannot> be used to set or 2108retrieve the autoflush setting. 2109 2110=head2 input_line_number 2111 2112 $z->input_line_number() 2113 $z->input_line_number(EXPR) 2114 2115This method always returns C<undef> when compressing. 2116 2117=head2 fileno 2118 2119 $z->fileno() 2120 fileno($z) 2121 2122If the C<$z> object is associated with a file or a filehandle, C<fileno> 2123will return the underlying file descriptor. Once the C<close> method is 2124called C<fileno> will return C<undef>. 2125 2126If the C<$z> object is associated with a buffer, this method will return 2127C<undef>. 2128 2129=head2 close 2130 2131 $z->close() ; 2132 close $z ; 2133 2134Flushes any pending compressed data and then closes the output file/buffer. 2135 2136For most versions of Perl this method will be automatically invoked if 2137the IO::Compress::Zip object is destroyed (either explicitly or by the 2138variable with the reference to the object going out of scope). The 2139exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In 2140these cases, the C<close> method will be called automatically, but 2141not until global destruction of all live objects when the program is 2142terminating. 2143 2144Therefore, if you want your scripts to be able to run on all versions 2145of Perl, you should call C<close> explicitly and not rely on automatic 2146closing. 2147 2148Returns true on success, otherwise 0. 2149 2150If the C<AutoClose> option has been enabled when the IO::Compress::Zip 2151object was created, and the object is associated with a file, the 2152underlying file will also be closed. 2153 2154=head2 newStream([OPTS]) 2155 2156Usage is 2157 2158 $z->newStream( [OPTS] ) 2159 2160Closes the current compressed data stream and starts a new one. 2161 2162OPTS consists of any of the options that are available when creating 2163the C<$z> object. 2164 2165See the L</"Constructor Options"> section for more details. 2166 2167=head2 deflateParams 2168 2169Usage is 2170 2171 $z->deflateParams 2172 2173TODO 2174 2175=head1 Importing 2176 2177A number of symbolic constants are required by some methods in 2178C<IO::Compress::Zip>. None are imported by default. 2179 2180=over 5 2181 2182=item :all 2183 2184Imports C<zip>, C<$ZipError> and all symbolic 2185constants that can be used by C<IO::Compress::Zip>. Same as doing this 2186 2187 use IO::Compress::Zip qw(zip $ZipError :constants) ; 2188 2189=item :constants 2190 2191Import all symbolic constants. Same as doing this 2192 2193 use IO::Compress::Zip qw(:flush :level :strategy :zip_method) ; 2194 2195=item :flush 2196 2197These symbolic constants are used by the C<flush> method. 2198 2199 Z_NO_FLUSH 2200 Z_PARTIAL_FLUSH 2201 Z_SYNC_FLUSH 2202 Z_FULL_FLUSH 2203 Z_FINISH 2204 Z_BLOCK 2205 2206=item :level 2207 2208These symbolic constants are used by the C<Level> option in the constructor. 2209 2210 Z_NO_COMPRESSION 2211 Z_BEST_SPEED 2212 Z_BEST_COMPRESSION 2213 Z_DEFAULT_COMPRESSION 2214 2215=item :strategy 2216 2217These symbolic constants are used by the C<Strategy> option in the constructor. 2218 2219 Z_FILTERED 2220 Z_HUFFMAN_ONLY 2221 Z_RLE 2222 Z_FIXED 2223 Z_DEFAULT_STRATEGY 2224 2225=item :zip_method 2226 2227These symbolic constants are used by the C<Method> option in the 2228constructor. 2229 2230 ZIP_CM_STORE 2231 ZIP_CM_DEFLATE 2232 ZIP_CM_BZIP2 2233 2234=back 2235 2236=head1 EXAMPLES 2237 2238=head2 Apache::GZip Revisited 2239 2240See L<IO::Compress::FAQ|IO::Compress::FAQ/"Apache::GZip Revisited"> 2241 2242=head2 Working with Net::FTP 2243 2244See L<IO::Compress::FAQ|IO::Compress::FAQ/"Compressed files and Net::FTP"> 2245 2246=head1 SUPPORT 2247 2248General feedback/questions/bug reports should be sent to 2249L<https://github.com/pmqs/IO-Compress/issues> (preferred) or 2250L<https://rt.cpan.org/Public/Dist/Display.html?Name=IO-Compress>. 2251 2252=head1 SEE ALSO 2253 2254L<Compress::Zlib>, L<IO::Compress::Gzip>, L<IO::Uncompress::Gunzip>, L<IO::Compress::Deflate>, L<IO::Uncompress::Inflate>, L<IO::Compress::RawDeflate>, L<IO::Uncompress::RawInflate>, L<IO::Compress::Bzip2>, L<IO::Uncompress::Bunzip2>, L<IO::Compress::Lzma>, L<IO::Uncompress::UnLzma>, L<IO::Compress::Xz>, L<IO::Uncompress::UnXz>, L<IO::Compress::Lzip>, L<IO::Uncompress::UnLzip>, L<IO::Compress::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Compress::Zstd>, L<IO::Uncompress::UnZstd>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress> 2255 2256L<IO::Compress::FAQ|IO::Compress::FAQ> 2257 2258L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>, 2259L<Archive::Tar|Archive::Tar>, 2260L<IO::Zlib|IO::Zlib> 2261 2262For RFC 1950, 1951 and 1952 see 2263L<https://datatracker.ietf.org/doc/html/rfc1950>, 2264L<https://datatracker.ietf.org/doc/html/rfc1951> and 2265L<https://datatracker.ietf.org/doc/html/rfc1952> 2266 2267The I<zlib> compression library was written by Jean-loup Gailly 2268C<gzip@prep.ai.mit.edu> and Mark Adler C<madler@alumni.caltech.edu>. 2269 2270The primary site for the I<zlib> compression library is 2271L<http://www.zlib.org>. 2272 2273The primary site for the I<zlib-ng> compression library is 2274L<https://github.com/zlib-ng/zlib-ng>. 2275 2276The primary site for gzip is L<http://www.gzip.org>. 2277 2278=head1 AUTHOR 2279 2280This module was written by Paul Marquess, C<pmqs@cpan.org>. 2281 2282=head1 MODIFICATION HISTORY 2283 2284See the Changes file. 2285 2286=head1 COPYRIGHT AND LICENSE 2287 2288Copyright (c) 2005-2024 Paul Marquess. All rights reserved. 2289 2290This program is free software; you can redistribute it and/or 2291modify it under the same terms as Perl itself. 2292