@ Override public InputStream getInputStream ( ) throws IOException { if ( ( zipEntryData == null ) || zipEntryData . isDirectory ( ) ) { return null ; } final ZipFileHandle zipFileHandle = rootContainer . getZipFileHandle ( ) ; // throws IOException ZipFile zipFile = zipFileHandle . open ( ) ; // The open must have a balancing close. That should be done by the caller. // In the worst case, 'finalize' makes sure it happens. final InputStream baseInputStream ; try { baseInputStream = zipFileHandle . getInputStream ( zipFile , zipEntryData . getPath ( ) ) ; // throws IOException } catch ( Throwable th ) { // Need to close here, since the caller never receives a wrapped // input stream to close. zipFileHandle . close ( ) ; throw th ; } if ( baseInputStream == null ) { throw new FileNotFoundException ( "Zip file [ " + zipFile . getName ( ) + " ]" + " failed to provide input stream for entry [ " + zipEntryData . getPath ( ) + " ]" ) ; } InputStream inputStream = new InputStream ( ) { private final InputStream wrappedInputStream = baseInputStream ; // Object lifecycle ... @ Override public synchronized void finalize ( ) throws Throwable { close ( ) ; // throws IOException super . finalize ( ) ; // throws Throwable } // Close ... private volatile boolean isClosed ; @ Override public void close ( ) throws IOException { if ( ! isClosed ) { synchronized ( this ) { if ( ! isClosed ) { try { wrappedInputStream . close ( ) ; // throws IOException } catch ( IOException e ) { // FFDC } zipFileHandle . close ( ) ; isClosed = true ; } } } } // Delegate methods ... @ Trivial @ Override public int read ( byte [ ] b ) throws IOException { return wrappedInputStream . read ( b ) ; } @ Trivial @ Override public int read ( byte [ ] b , int off , int len ) throws IOException { return wrappedInputStream . read ( b , off , len ) ; // throws IOException } @ Trivial @ Override public long skip ( long n ) throws IOException { return wrappedInputStream . skip ( n ) ; // throws IOException } @ Trivial @ Override public int available ( ) throws IOException { return wrappedInputStream . available ( ) ; // throws IOException } @ SuppressWarnings ( "sync-override" ) @ Trivial @ Override public void mark ( int readlimit ) { wrappedInputStream . mark ( readlimit ) ; } @ SuppressWarnings ( "sync-override" ) @ Trivial @ Override public void reset ( ) throws IOException { wrappedInputStream . reset ( ) ; // throws IOException } @ Trivial @ Override public boolean markSupported ( ) { return wrappedInputStream . markSupported ( ) ; } @ Override public int read ( ) throws IOException { return wrappedInputStream . read ( ) ; // throws IOException } } ; return inputStream ; }
Obtain an input stream for the entry .