< prev index next >

src/java.base/share/classes/java/util/zip/ZipOutputStream.java

Print this page
rev 11478 : 8073497: Lazy conversion of ZipEntry time
Reviewed-by: sherman, plevart
   1 /*
   2  * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  44 public
  45 class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
  46 
  47     /**
  48      * Whether to use ZIP64 for zip files with more than 64k entries.
  49      * Until ZIP64 support in zip implementations is ubiquitous, this
  50      * system property allows the creation of zip files which can be
  51      * read by legacy zip implementations which tolerate "incorrect"
  52      * total entry count fields, such as the ones in jdk6, and even
  53      * some in jdk7.
  54      */
  55     private static final boolean inhibitZip64 =
  56         Boolean.parseBoolean(
  57             java.security.AccessController.doPrivileged(
  58                 new sun.security.action.GetPropertyAction(
  59                     "jdk.util.zip.inhibitZip64", "false")));
  60 
  61     private static class XEntry {
  62         final ZipEntry entry;
  63         final long offset;
  64         long dostime;    // last modification time in msdos format
  65         public XEntry(ZipEntry entry, long offset) {
  66             this.entry = entry;
  67             this.offset = offset;
  68         }
  69     }
  70 
  71     private XEntry current;
  72     private Vector<XEntry> xentries = new Vector<>();
  73     private HashSet<String> names = new HashSet<>();
  74     private CRC32 crc = new CRC32();
  75     private long written = 0;
  76     private long locoff = 0;
  77     private byte[] comment;
  78     private int method = DEFLATED;
  79     private boolean finished;
  80 
  81     private boolean closed = false;
  82 
  83     private final ZipCoder zc;
  84 


 175      */
 176     public void setLevel(int level) {
 177         def.setLevel(level);
 178     }
 179 
 180     /**
 181      * Begins writing a new ZIP file entry and positions the stream to the
 182      * start of the entry data. Closes the current entry if still active.
 183      * The default compression method will be used if no compression method
 184      * was specified for the entry, and the current time will be used if
 185      * the entry has no set modification time.
 186      * @param e the ZIP entry to be written
 187      * @exception ZipException if a ZIP format error has occurred
 188      * @exception IOException if an I/O error has occurred
 189      */
 190     public void putNextEntry(ZipEntry e) throws IOException {
 191         ensureOpen();
 192         if (current != null) {
 193             closeEntry();       // close previous entry
 194         }
 195         if (e.time == -1) {
 196             // by default, do NOT use extended timestamps in extra
 197             // data, for now.
 198             e.setTime(System.currentTimeMillis());
 199         }
 200         if (e.method == -1) {
 201             e.method = method;  // use default method
 202         }
 203         // store size, compressed size, and crc-32 in LOC header
 204         e.flag = 0;
 205         switch (e.method) {
 206         case DEFLATED:
 207             // store size, compressed size, and crc-32 in data descriptor
 208             // immediately following the compressed entry data
 209             if (e.size  == -1 || e.csize == -1 || e.crc   == -1)
 210                 e.flag = 8;
 211 
 212             break;
 213         case STORED:
 214             // compressed size, uncompressed size, and crc-32 must all be
 215             // set for entries using STORED compression method


 372      * Closes the ZIP output stream as well as the stream being filtered.
 373      * @exception ZipException if a ZIP file error has occurred
 374      * @exception IOException if an I/O error has occurred
 375      */
 376     public void close() throws IOException {
 377         if (!closed) {
 378             super.close();
 379             closed = true;
 380         }
 381     }
 382 
 383     /*
 384      * Writes local file (LOC) header for specified entry.
 385      */
 386     private void writeLOC(XEntry xentry) throws IOException {
 387         ZipEntry e = xentry.entry;
 388         int flag = e.flag;
 389         boolean hasZip64 = false;
 390         int elen = getExtraLen(e.extra);
 391 
 392         // keep a copy of dostime for writeCEN(), otherwise the tz
 393         // sensitive local time entries in loc and cen might be
 394         // different if the default tz get changed during writeLOC()
 395         // and writeCEN()
 396         xentry.dostime = javaToDosTime(e.time);
 397 
 398         writeInt(LOCSIG);               // LOC header signature
 399         if ((flag & 8) == 8) {
 400             writeShort(version(e));     // version needed to extract
 401             writeShort(flag);           // general purpose bit flag
 402             writeShort(e.method);       // compression method
 403             writeInt(xentry.dostime);   // last modification time
 404             // store size, uncompressed size, and crc-32 in data descriptor
 405             // immediately following compressed entry data
 406             writeInt(0);
 407             writeInt(0);
 408             writeInt(0);
 409         } else {
 410             if (e.csize >= ZIP64_MAGICVAL || e.size >= ZIP64_MAGICVAL) {
 411                 hasZip64 = true;
 412                 writeShort(45);         // ver 4.5 for zip64
 413             } else {
 414                 writeShort(version(e)); // version needed to extract
 415             }
 416             writeShort(flag);           // general purpose bit flag
 417             writeShort(e.method);       // compression method
 418             writeInt(xentry.dostime);   // last modification time
 419             writeInt(e.crc);            // crc-32
 420             if (hasZip64) {
 421                 writeInt(ZIP64_MAGICVAL);
 422                 writeInt(ZIP64_MAGICVAL);
 423                 elen += 20;        //headid(2) + size(2) + size(8) + csize(8)
 424             } else {
 425                 writeInt(e.csize);  // compressed size
 426                 writeInt(e.size);   // uncompressed size
 427             }
 428         }
 429         byte[] nameBytes = zc.getBytes(e.name);
 430         writeShort(nameBytes.length);
 431 
 432         int elenEXTT = 0;               // info-zip extended timestamp
 433         int flagEXTT = 0;
 434         if (e.mtime != null) {
 435             elenEXTT += 4;
 436             flagEXTT |= EXTT_FLAG_LMT;
 437         }
 438         if (e.atime != null) {


 505         if (e.size >= ZIP64_MAGICVAL) {
 506             size = ZIP64_MAGICVAL;    // size(8)
 507             elenZIP64 += 8;
 508             hasZip64 = true;
 509         }
 510         if (xentry.offset >= ZIP64_MAGICVAL) {
 511             offset = ZIP64_MAGICVAL;
 512             elenZIP64 += 8;              // offset(8)
 513             hasZip64 = true;
 514         }
 515         writeInt(CENSIG);           // CEN header signature
 516         if (hasZip64) {
 517             writeShort(45);         // ver 4.5 for zip64
 518             writeShort(45);
 519         } else {
 520             writeShort(version);    // version made by
 521             writeShort(version);    // version needed to extract
 522         }
 523         writeShort(flag);           // general purpose bit flag
 524         writeShort(e.method);       // compression method
 525         // use the copy in xentry, which has been converted
 526         // from e.time in writeLOC()
 527         writeInt(xentry.dostime);   // last modification time
 528         writeInt(e.crc);            // crc-32
 529         writeInt(csize);            // compressed size
 530         writeInt(size);             // uncompressed size
 531         byte[] nameBytes = zc.getBytes(e.name);
 532         writeShort(nameBytes.length);
 533 
 534         int elen = getExtraLen(e.extra);
 535         if (hasZip64) {
 536             elen += (elenZIP64 + 4);// + headid(2) + datasize(2)
 537         }
 538         // cen info-zip extended timestamp only outputs mtime
 539         // but set the flag for a/ctime, if present in loc
 540         int flagEXTT = 0;
 541         if (e.mtime != null) {
 542             elen += 4;              // + mtime(4)
 543             flagEXTT |= EXTT_FLAG_LMT;
 544         }
 545         if (e.atime != null) {
 546             flagEXTT |= EXTT_FLAG_LAT;
 547         }


   1 /*
   2  * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  44 public
  45 class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
  46 
  47     /**
  48      * Whether to use ZIP64 for zip files with more than 64k entries.
  49      * Until ZIP64 support in zip implementations is ubiquitous, this
  50      * system property allows the creation of zip files which can be
  51      * read by legacy zip implementations which tolerate "incorrect"
  52      * total entry count fields, such as the ones in jdk6, and even
  53      * some in jdk7.
  54      */
  55     private static final boolean inhibitZip64 =
  56         Boolean.parseBoolean(
  57             java.security.AccessController.doPrivileged(
  58                 new sun.security.action.GetPropertyAction(
  59                     "jdk.util.zip.inhibitZip64", "false")));
  60 
  61     private static class XEntry {
  62         final ZipEntry entry;
  63         final long offset;

  64         public XEntry(ZipEntry entry, long offset) {
  65             this.entry = entry;
  66             this.offset = offset;
  67         }
  68     }
  69 
  70     private XEntry current;
  71     private Vector<XEntry> xentries = new Vector<>();
  72     private HashSet<String> names = new HashSet<>();
  73     private CRC32 crc = new CRC32();
  74     private long written = 0;
  75     private long locoff = 0;
  76     private byte[] comment;
  77     private int method = DEFLATED;
  78     private boolean finished;
  79 
  80     private boolean closed = false;
  81 
  82     private final ZipCoder zc;
  83 


 174      */
 175     public void setLevel(int level) {
 176         def.setLevel(level);
 177     }
 178 
 179     /**
 180      * Begins writing a new ZIP file entry and positions the stream to the
 181      * start of the entry data. Closes the current entry if still active.
 182      * The default compression method will be used if no compression method
 183      * was specified for the entry, and the current time will be used if
 184      * the entry has no set modification time.
 185      * @param e the ZIP entry to be written
 186      * @exception ZipException if a ZIP format error has occurred
 187      * @exception IOException if an I/O error has occurred
 188      */
 189     public void putNextEntry(ZipEntry e) throws IOException {
 190         ensureOpen();
 191         if (current != null) {
 192             closeEntry();       // close previous entry
 193         }
 194         if (e.xdostime == -1) {
 195             // by default, do NOT use extended timestamps in extra
 196             // data, for now.
 197             e.setTime(System.currentTimeMillis());
 198         }
 199         if (e.method == -1) {
 200             e.method = method;  // use default method
 201         }
 202         // store size, compressed size, and crc-32 in LOC header
 203         e.flag = 0;
 204         switch (e.method) {
 205         case DEFLATED:
 206             // store size, compressed size, and crc-32 in data descriptor
 207             // immediately following the compressed entry data
 208             if (e.size  == -1 || e.csize == -1 || e.crc   == -1)
 209                 e.flag = 8;
 210 
 211             break;
 212         case STORED:
 213             // compressed size, uncompressed size, and crc-32 must all be
 214             // set for entries using STORED compression method


 371      * Closes the ZIP output stream as well as the stream being filtered.
 372      * @exception ZipException if a ZIP file error has occurred
 373      * @exception IOException if an I/O error has occurred
 374      */
 375     public void close() throws IOException {
 376         if (!closed) {
 377             super.close();
 378             closed = true;
 379         }
 380     }
 381 
 382     /*
 383      * Writes local file (LOC) header for specified entry.
 384      */
 385     private void writeLOC(XEntry xentry) throws IOException {
 386         ZipEntry e = xentry.entry;
 387         int flag = e.flag;
 388         boolean hasZip64 = false;
 389         int elen = getExtraLen(e.extra);
 390 






 391         writeInt(LOCSIG);               // LOC header signature
 392         if ((flag & 8) == 8) {
 393             writeShort(version(e));     // version needed to extract
 394             writeShort(flag);           // general purpose bit flag
 395             writeShort(e.method);       // compression method
 396             writeInt(e.xdostime);       // last modification time
 397             // store size, uncompressed size, and crc-32 in data descriptor
 398             // immediately following compressed entry data
 399             writeInt(0);
 400             writeInt(0);
 401             writeInt(0);
 402         } else {
 403             if (e.csize >= ZIP64_MAGICVAL || e.size >= ZIP64_MAGICVAL) {
 404                 hasZip64 = true;
 405                 writeShort(45);         // ver 4.5 for zip64
 406             } else {
 407                 writeShort(version(e)); // version needed to extract
 408             }
 409             writeShort(flag);           // general purpose bit flag
 410             writeShort(e.method);       // compression method
 411             writeInt(e.xdostime);       // last modification time
 412             writeInt(e.crc);            // crc-32
 413             if (hasZip64) {
 414                 writeInt(ZIP64_MAGICVAL);
 415                 writeInt(ZIP64_MAGICVAL);
 416                 elen += 20;        //headid(2) + size(2) + size(8) + csize(8)
 417             } else {
 418                 writeInt(e.csize);  // compressed size
 419                 writeInt(e.size);   // uncompressed size
 420             }
 421         }
 422         byte[] nameBytes = zc.getBytes(e.name);
 423         writeShort(nameBytes.length);
 424 
 425         int elenEXTT = 0;               // info-zip extended timestamp
 426         int flagEXTT = 0;
 427         if (e.mtime != null) {
 428             elenEXTT += 4;
 429             flagEXTT |= EXTT_FLAG_LMT;
 430         }
 431         if (e.atime != null) {


 498         if (e.size >= ZIP64_MAGICVAL) {
 499             size = ZIP64_MAGICVAL;    // size(8)
 500             elenZIP64 += 8;
 501             hasZip64 = true;
 502         }
 503         if (xentry.offset >= ZIP64_MAGICVAL) {
 504             offset = ZIP64_MAGICVAL;
 505             elenZIP64 += 8;              // offset(8)
 506             hasZip64 = true;
 507         }
 508         writeInt(CENSIG);           // CEN header signature
 509         if (hasZip64) {
 510             writeShort(45);         // ver 4.5 for zip64
 511             writeShort(45);
 512         } else {
 513             writeShort(version);    // version made by
 514             writeShort(version);    // version needed to extract
 515         }
 516         writeShort(flag);           // general purpose bit flag
 517         writeShort(e.method);       // compression method
 518         writeInt(e.xdostime);       // last modification time


 519         writeInt(e.crc);            // crc-32
 520         writeInt(csize);            // compressed size
 521         writeInt(size);             // uncompressed size
 522         byte[] nameBytes = zc.getBytes(e.name);
 523         writeShort(nameBytes.length);
 524 
 525         int elen = getExtraLen(e.extra);
 526         if (hasZip64) {
 527             elen += (elenZIP64 + 4);// + headid(2) + datasize(2)
 528         }
 529         // cen info-zip extended timestamp only outputs mtime
 530         // but set the flag for a/ctime, if present in loc
 531         int flagEXTT = 0;
 532         if (e.mtime != null) {
 533             elen += 4;              // + mtime(4)
 534             flagEXTT |= EXTT_FLAG_LMT;
 535         }
 536         if (e.atime != null) {
 537             flagEXTT |= EXTT_FLAG_LAT;
 538         }


< prev index next >