< prev index next >

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

Print this page




 327 
 328     // the outstanding inputstreams that need to be closed,
 329     // mapped to the inflater objects they use.
 330     private final Map<InputStream, Inflater> streams = new WeakHashMap<>();
 331 
 332     /**
 333      * Returns an input stream for reading the contents of the specified
 334      * zip file entry.
 335      *
 336      * <p> Closing this ZIP file will, in turn, close all input
 337      * streams that have been returned by invocations of this method.
 338      *
 339      * @param entry the zip file entry
 340      * @return the input stream for reading the contents of the specified
 341      * zip file entry.
 342      * @throws ZipException if a ZIP format error has occurred
 343      * @throws IOException if an I/O error has occurred
 344      * @throws IllegalStateException if the zip file has been closed
 345      */
 346     public InputStream getInputStream(ZipEntry entry) throws IOException {




















 347         if (entry == null) {
 348             throw new NullPointerException("entry");
 349         }









 350         long jzentry = 0;
 351         ZipFileInputStream in = null;
 352         synchronized (this) {
 353             ensureOpen();
 354             if (!zc.isUTF8() && (entry.flag & EFS) != 0) {
 355                 jzentry = getEntry(jzfile, zc.getBytesUTF8(entry.name), false);
 356             } else {
 357                 jzentry = getEntry(jzfile, zc.getBytes(entry.name), false);
 358             }
 359             if (jzentry == 0) {
 360                 return null;
 361             }
 362             in = new ZipFileInputStream(jzentry);
 363 
 364             switch (getEntryMethod(jzentry)) {
 365             case STORED:












 366                 synchronized (streams) {
 367                     streams.put(in, null);
 368                 }
 369                 return in;
 370             case DEFLATED:
 371                 // MORE: Compute good size for inflater stream:
 372                 long size = getEntrySize(jzentry) + 2; // Inflater likes a bit of slack
 373                 if (size > 65536) size = 8192;
 374                 if (size <= 0) size = 4096;
 375                 Inflater inf = getInflater();












 376                 InputStream is =
 377                     new ZipFileInflaterInputStream(in, inf, (int)size);
 378                 synchronized (streams) {
 379                     streams.put(is, inf);
 380                 }
 381                 return is;
 382             default:
 383                 throw new ZipException("invalid compression method");
 384             }
 385         }
 386     }
 387 
 388     private class ZipFileInflaterInputStream extends InflaterInputStream {
 389         private volatile boolean closeRequested = false;
 390         private boolean eof = false;
 391         private final ZipFileInputStream zfin;
 392 
 393         ZipFileInflaterInputStream(ZipFileInputStream zfin, Inflater inf,
 394                 int size) {
 395             super(zfin, inf, size);


 679             throw new IllegalStateException("The object is not initialized.");
 680         }
 681     }
 682 
 683     private void ensureOpenOrZipException() throws IOException {
 684         if (closeRequested) {
 685             throw new ZipException("ZipFile closed");
 686         }
 687     }
 688 
 689     /*
 690      * Inner class implementing the input stream used to read a
 691      * (possibly compressed) zip file entry.
 692      */
 693    private class ZipFileInputStream extends InputStream {
 694         private volatile boolean zfisCloseRequested = false;
 695         protected long jzentry; // address of jzentry data
 696         private   long pos;     // current position within entry data
 697         protected long rem;     // number of remaining bytes within entry
 698         protected long size;    // uncompressed size of this entry

 699 
 700         ZipFileInputStream(long jzentry) {
 701             pos = 0;
 702             rem = getEntryCSize(jzentry);
 703             size = getEntrySize(jzentry);
 704             this.jzentry = jzentry;

 705         }
 706 
 707         public int read(byte b[], int off, int len) throws IOException {










 708             synchronized (ZipFile.this) {
 709                 long rem = this.rem;
 710                 long pos = this.pos;
 711                 if (rem == 0) {
 712                     return -1;
 713                 }
 714                 if (len <= 0) {
 715                     return 0;
 716                 }
 717                 if (len > rem) {
 718                     len = (int) rem;
 719                 }
 720 
 721                 // Check if ZipFile open
 722                 ensureOpenOrZipException();
 723                 len = ZipFile.read(ZipFile.this.jzfile, jzentry, pos, b,
 724                                    off, len);
 725                 if (len > 0) {
 726                     this.pos = (pos + len);
 727                     this.rem = (rem - len);




 327 
 328     // the outstanding inputstreams that need to be closed,
 329     // mapped to the inflater objects they use.
 330     private final Map<InputStream, Inflater> streams = new WeakHashMap<>();
 331 
 332     /**
 333      * Returns an input stream for reading the contents of the specified
 334      * zip file entry.
 335      *
 336      * <p> Closing this ZIP file will, in turn, close all input
 337      * streams that have been returned by invocations of this method.
 338      *
 339      * @param entry the zip file entry
 340      * @return the input stream for reading the contents of the specified
 341      * zip file entry.
 342      * @throws ZipException if a ZIP format error has occurred
 343      * @throws IOException if an I/O error has occurred
 344      * @throws IllegalStateException if the zip file has been closed
 345      */
 346     public InputStream getInputStream(ZipEntry entry) throws IOException {
 347         return getInputStream(entry, null);
 348     }
 349 
 350     /**
 351      * Returns an input stream for reading the contents of the specified
 352      * zip file entry.
 353      *
 354      * <p> Closing this ZIP file will, in turn, close all input
 355      * streams that have been returned by invocations of this method.
 356      *
 357      * @param entry the zip file entry
 358      * @param zipCryption instance of ZipCryption
 359      * @return the input stream for reading the contents of the specified
 360      * zip file entry.
 361      * @throws ZipException if a ZIP format error has occurred
 362      * @throws IOException if an I/O error has occurred
 363      * @throws IllegalStateException if the zip file has been closed
 364      */
 365     public InputStream getInputStream(ZipEntry entry, ZipCryption zipCryption)
 366                                                             throws IOException {
 367         if (entry == null) {
 368             throw new NullPointerException("entry");
 369         }
 370 
 371         if ((entry.flag & 1) == 1) {
 372             if (zipCryption == null) {
 373                 throw new ZipException("Passphrase is required.");
 374             } else {
 375                 zipCryption.reset();
 376             }
 377         }
 378 
 379         long jzentry = 0;
 380         ZipFileInputStream in = null;
 381         synchronized (this) {
 382             ensureOpen();
 383             if (!zc.isUTF8() && (entry.flag & EFS) != 0) {
 384                 jzentry = getEntry(jzfile, zc.getBytesUTF8(entry.name), false);
 385             } else {
 386                 jzentry = getEntry(jzfile, zc.getBytes(entry.name), false);
 387             }
 388             if (jzentry == 0) {
 389                 return null;
 390             }
 391             in = new ZipFileInputStream(jzentry, zipCryption);
 392 
 393             switch (getEntryMethod(jzentry)) {
 394             case STORED:
 395 
 396                 if ((entry.flag & 1) == 1) {
 397                     byte[] encryptionHeader =
 398                                 new byte[zipCryption.getEncryptionHeaderSize()];
 399                     in.readRaw(encryptionHeader, 0, encryptionHeader.length);
 400                     zipCryption.decryptBytes(encryptionHeader);
 401 
 402                     if (!zipCryption.isValid(entry, encryptionHeader)) {
 403                         throw new ZipException("possibly incorrect passphrase");
 404                     }
 405                 }
 406 
 407                 synchronized (streams) {
 408                     streams.put(in, null);
 409                 }
 410                 return in;
 411             case DEFLATED:
 412                 // MORE: Compute good size for inflater stream:
 413                 long size = getEntrySize(jzentry) + 2; // Inflater likes a bit of slack
 414                 if (size > 65536) size = 8192;
 415                 if (size <= 0) size = 4096;
 416                 Inflater inf = getInflater();
 417 
 418                 if ((entry.flag & 1) == 1) {
 419                     byte[] encryptionHeader =
 420                                 new byte[zipCryption.getEncryptionHeaderSize()];
 421                     in.readRaw(encryptionHeader, 0, encryptionHeader.length);
 422                     zipCryption.decryptBytes(encryptionHeader);
 423 
 424                     if (!zipCryption.isValid(entry, encryptionHeader)) {
 425                         throw new ZipException("possibly incorrect passphrase");
 426                     }
 427                 }
 428 
 429                 InputStream is =
 430                     new ZipFileInflaterInputStream(in, inf, (int)size);
 431                 synchronized (streams) {
 432                     streams.put(is, inf);
 433                 }
 434                 return is;
 435             default:
 436                 throw new ZipException("invalid compression method");
 437             }
 438         }
 439     }
 440 
 441     private class ZipFileInflaterInputStream extends InflaterInputStream {
 442         private volatile boolean closeRequested = false;
 443         private boolean eof = false;
 444         private final ZipFileInputStream zfin;
 445 
 446         ZipFileInflaterInputStream(ZipFileInputStream zfin, Inflater inf,
 447                 int size) {
 448             super(zfin, inf, size);


 732             throw new IllegalStateException("The object is not initialized.");
 733         }
 734     }
 735 
 736     private void ensureOpenOrZipException() throws IOException {
 737         if (closeRequested) {
 738             throw new ZipException("ZipFile closed");
 739         }
 740     }
 741 
 742     /*
 743      * Inner class implementing the input stream used to read a
 744      * (possibly compressed) zip file entry.
 745      */
 746    private class ZipFileInputStream extends InputStream {
 747         private volatile boolean zfisCloseRequested = false;
 748         protected long jzentry; // address of jzentry data
 749         private   long pos;     // current position within entry data
 750         protected long rem;     // number of remaining bytes within entry
 751         protected long size;    // uncompressed size of this entry
 752         private ZipCryption zipCryption; // ZIP encrypt/decrypt engine
 753 
 754         ZipFileInputStream(long jzentry, ZipCryption zipCryption) {
 755             pos = 0;
 756             rem = getEntryCSize(jzentry);
 757             size = getEntrySize(jzentry);
 758             this.jzentry = jzentry;
 759             this.zipCryption = zipCryption;
 760         }
 761 
 762         public int read(byte b[], int off, int len) throws IOException {
 763             len = readRaw(b, off, len);
 764 
 765             if (zipCryption != null) {
 766                 zipCryption.decryptBytes(b, off, len);
 767             }
 768 
 769             return len;
 770         }
 771 
 772         public int readRaw(byte b[], int off, int len) throws IOException {
 773             synchronized (ZipFile.this) {
 774                 long rem = this.rem;
 775                 long pos = this.pos;
 776                 if (rem == 0) {
 777                     return -1;
 778                 }
 779                 if (len <= 0) {
 780                     return 0;
 781                 }
 782                 if (len > rem) {
 783                     len = (int) rem;
 784                 }
 785 
 786                 // Check if ZipFile open
 787                 ensureOpenOrZipException();
 788                 len = ZipFile.read(ZipFile.this.jzfile, jzentry, pos, b,
 789                                    off, len);
 790                 if (len > 0) {
 791                     this.pos = (pos + len);
 792                     this.rem = (rem - len);


< prev index next >