src/share/classes/java/util/zip/ZipFile.java

Print this page
rev 7020 : 8012645: Stream methods on BitSet, Random, ThreadLocalRandom, ZipFile
Contributed-by: akhil.arora@oracle.com, brian.goetz@oracle.com


  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
  23  * questions.
  24  */
  25 
  26 package java.util.zip;
  27 
  28 import java.io.Closeable;
  29 import java.io.InputStream;
  30 import java.io.IOException;
  31 import java.io.EOFException;
  32 import java.io.File;
  33 import java.nio.charset.Charset;
  34 import java.nio.charset.StandardCharsets;
  35 import java.util.ArrayDeque;
  36 import java.util.Deque;
  37 import java.util.Enumeration;
  38 import java.util.HashMap;

  39 import java.util.Map;
  40 import java.util.NoSuchElementException;


  41 import java.util.WeakHashMap;
  42 import java.security.AccessController;
  43 import sun.security.action.GetPropertyAction;

  44 import static java.util.zip.ZipConstants64.*;
  45 
  46 /**
  47  * This class is used to read entries from a zip file.
  48  *
  49  * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
  50  * or method in this class will cause a {@link NullPointerException} to be
  51  * thrown.
  52  *
  53  * @author      David Connelly
  54  */
  55 public
  56 class ZipFile implements ZipConstants, Closeable {
  57     private long jzfile;  // address of jzfile data
  58     private String name;  // zip file name
  59     private int total;    // total number of entries
  60     private volatile boolean closeRequested = false;
  61 
  62     private static final int STORED = ZipEntry.STORED;
  63     private static final int DEFLATED = ZipEntry.DEFLATED;


 454     private void releaseInflater(Inflater inf) {
 455         if (false == inf.ended()) {
 456             inf.reset();
 457             synchronized (inflaterCache) {
 458                 inflaterCache.add(inf);
 459             }
 460         }
 461     }
 462 
 463     // List of available Inflater objects for decompression
 464     private Deque<Inflater> inflaterCache = new ArrayDeque<>();
 465 
 466     /**
 467      * Returns the path name of the ZIP file.
 468      * @return the path name of the ZIP file
 469      */
 470     public String getName() {
 471         return name;
 472     }
 473 
 474     /**
 475      * Returns an enumeration of the ZIP file entries.
 476      * @return an enumeration of the ZIP file entries
 477      * @throws IllegalStateException if the zip file has been closed
 478      */
 479     public Enumeration<? extends ZipEntry> entries() {
 480         ensureOpen();
 481         return new Enumeration<ZipEntry>() {
 482                 private int i = 0;





 483                 public boolean hasMoreElements() {




 484                     synchronized (ZipFile.this) {
 485                         ensureOpen();
 486                         return i < total;
 487                     }
 488                 }
 489                 public ZipEntry nextElement() throws NoSuchElementException {





 490                     synchronized (ZipFile.this) {
 491                         ensureOpen();
 492                         if (i >= total) {
 493                             throw new NoSuchElementException();
 494                         }
 495                         long jzentry = getNextEntry(jzfile, i++);
 496                         if (jzentry == 0) {
 497                             String message;
 498                             if (closeRequested) {
 499                                 message = "ZipFile concurrently closed";
 500                             } else {
 501                                 message = getZipMessage(ZipFile.this.jzfile);
 502                             }
 503                             throw new ZipError("jzentry == 0" +
 504                                                ",\n jzfile = " + ZipFile.this.jzfile +
 505                                                ",\n total = " + ZipFile.this.total +
 506                                                ",\n name = " + ZipFile.this.name +
 507                                                ",\n i = " + i +
 508                                                ",\n message = " + message
 509                                 );
 510                         }
 511                         ZipEntry ze = getZipEntry(null, jzentry);
 512                         freeEntry(jzfile, jzentry);
 513                         return ze;
 514                     }
 515                 }
 516             };





















 517     }
 518 
 519     private ZipEntry getZipEntry(String name, long jzentry) {
 520         ZipEntry e = new ZipEntry();
 521         e.flag = getEntryFlag(jzentry);  // get the flag first
 522         if (name != null) {
 523             e.name = name;
 524         } else {
 525             byte[] bname = getEntryBytes(jzentry, JZENTRY_NAME);
 526             if (!zc.isUTF8() && (e.flag & EFS) != 0) {
 527                 e.name = zc.toStringUTF8(bname, bname.length);
 528             } else {
 529                 e.name = zc.toString(bname, bname.length);
 530             }
 531         }
 532         e.time = getEntryTime(jzentry);
 533         e.crc = getEntryCrc(jzentry);
 534         e.size = getEntrySize(jzentry);
 535         e. csize = getEntryCSize(jzentry);
 536         e.method = getEntryMethod(jzentry);




  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
  23  * questions.
  24  */
  25 
  26 package java.util.zip;
  27 
  28 import java.io.Closeable;
  29 import java.io.InputStream;
  30 import java.io.IOException;
  31 import java.io.EOFException;
  32 import java.io.File;
  33 import java.nio.charset.Charset;
  34 import java.nio.charset.StandardCharsets;
  35 import java.util.ArrayDeque;
  36 import java.util.Deque;
  37 import java.util.Enumeration;
  38 import java.util.HashMap;
  39 import java.util.Iterator;
  40 import java.util.Map;
  41 import java.util.NoSuchElementException;
  42 import java.util.Spliterator;
  43 import java.util.Spliterators;
  44 import java.util.WeakHashMap;
  45 import java.util.stream.Stream;
  46 import java.util.stream.StreamSupport;
  47 
  48 import static java.util.zip.ZipConstants64.*;
  49 
  50 /**
  51  * This class is used to read entries from a zip file.
  52  *
  53  * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
  54  * or method in this class will cause a {@link NullPointerException} to be
  55  * thrown.
  56  *
  57  * @author      David Connelly
  58  */
  59 public
  60 class ZipFile implements ZipConstants, Closeable {
  61     private long jzfile;  // address of jzfile data
  62     private String name;  // zip file name
  63     private int total;    // total number of entries
  64     private volatile boolean closeRequested = false;
  65 
  66     private static final int STORED = ZipEntry.STORED;
  67     private static final int DEFLATED = ZipEntry.DEFLATED;


 458     private void releaseInflater(Inflater inf) {
 459         if (false == inf.ended()) {
 460             inf.reset();
 461             synchronized (inflaterCache) {
 462                 inflaterCache.add(inf);
 463             }
 464         }
 465     }
 466 
 467     // List of available Inflater objects for decompression
 468     private Deque<Inflater> inflaterCache = new ArrayDeque<>();
 469 
 470     /**
 471      * Returns the path name of the ZIP file.
 472      * @return the path name of the ZIP file
 473      */
 474     public String getName() {
 475         return name;
 476     }
 477 
 478     protected class ZipEntryIterator implements Enumeration<ZipEntry>, Iterator<ZipEntry> {







 479         private int i = 0;
 480 
 481         public ZipEntryIterator() {
 482             ensureOpen();
 483         }
 484 
 485         public boolean hasMoreElements() {
 486             return hasNext();
 487         }
 488 
 489         public boolean hasNext() {
 490             synchronized (ZipFile.this) {
 491                 ensureOpen();
 492                 return i < total;
 493             }
 494         }
 495 
 496         public ZipEntry nextElement() {
 497             return next();
 498         }
 499 
 500         public ZipEntry next() {
 501             synchronized (ZipFile.this) {
 502                 ensureOpen();
 503                 if (i >= total) {
 504                     throw new NoSuchElementException();
 505                 }
 506                 long jzentry = getNextEntry(jzfile, i++);
 507                 if (jzentry == 0) {
 508                     String message;
 509                     if (closeRequested) {
 510                         message = "ZipFile concurrently closed";
 511                     } else {
 512                         message = getZipMessage(ZipFile.this.jzfile);
 513                     }
 514                     throw new ZipError("jzentry == 0" +
 515                                        ",\n jzfile = " + ZipFile.this.jzfile +
 516                                        ",\n total = " + ZipFile.this.total +
 517                                        ",\n name = " + ZipFile.this.name +
 518                                        ",\n i = " + i +
 519                                        ",\n message = " + message
 520                         );
 521                 }
 522                 ZipEntry ze = getZipEntry(null, jzentry);
 523                 freeEntry(jzfile, jzentry);
 524                 return ze;
 525             }
 526         }
 527     }
 528 
 529     /**
 530      * Returns an enumeration of the ZIP file entries.
 531      * @return an enumeration of the ZIP file entries
 532      * @throws IllegalStateException if the zip file has been closed
 533      */
 534     public Enumeration<? extends ZipEntry> entries() {
 535         return new ZipEntryIterator();
 536     }
 537 
 538     /**
 539      * Return a {@code Stream} of the ZIP file entries.
 540      *
 541      * @return a {@code Stream} of entries in this ZIP file
 542      * @throws IllegalStateException if the zip file has been closed
 543      * @since 1.8
 544      */
 545     public Stream<? extends ZipEntry> stream() {
 546         return StreamSupport.stream(Spliterators.spliterator(
 547                 new ZipEntryIterator(), size(),
 548                 Spliterator.DISTINCT | Spliterator.IMMUTABLE | Spliterator.NONNULL));
 549     }
 550 
 551     private ZipEntry getZipEntry(String name, long jzentry) {
 552         ZipEntry e = new ZipEntry();
 553         e.flag = getEntryFlag(jzentry);  // get the flag first
 554         if (name != null) {
 555             e.name = name;
 556         } else {
 557             byte[] bname = getEntryBytes(jzentry, JZENTRY_NAME);
 558             if (!zc.isUTF8() && (e.flag & EFS) != 0) {
 559                 e.name = zc.toStringUTF8(bname, bname.length);
 560             } else {
 561                 e.name = zc.toString(bname, bname.length);
 562             }
 563         }
 564         e.time = getEntryTime(jzentry);
 565         e.crc = getEntryCrc(jzentry);
 566         e.size = getEntrySize(jzentry);
 567         e. csize = getEntryCSize(jzentry);
 568         e.method = getEntryMethod(jzentry);