< prev index next >

src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java

Print this page
rev 54493 : imported patch def

@@ -1185,10 +1185,14 @@
 
         if (e.bytes == null && e.file == null)    // dir, 0-length data
             return 0;
 
         long written = 0;
+        if (e.bytes != null && e.crc != 0) {
+            // precompressed entry, write directly to output stream
+            os.write(e.bytes, 0, e.bytes.length);
+        } else {
         try (OutputStream os2 = e.method == METHOD_STORED ?
             new EntryOutputStreamCRC32(e, os) : new EntryOutputStreamDef(e, os)) {
             if (e.bytes != null) {                 // in-memory
                 os2.write(e.bytes, 0, e.bytes.length);
             } else if (e.file != null) {           // tmp file

@@ -1199,10 +1203,11 @@
                 }
                 Files.delete(e.file);
                 tmppaths.remove(e.file);
             }
         }
+        }
         written += e.csize;
         if ((e.flag & FLAG_DATADESCR) != 0) {
             written += e.writeEXT(os);
         }
         return written;

@@ -1325,10 +1330,14 @@
         OutputStream os;
         if (useTempFile) {
             e.file = getTempPathForEntry(null);
             os = Files.newOutputStream(e.file, WRITE);
         } else {
+            if (defaultMethod == METHOD_DEFLATED) {
+                return new DeflatingByteArrayEntryOutputStream(e,
+                        new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192));
+            }
             os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192);
         }
         return new EntryOutputStream(e, os);
     }
 

@@ -1368,10 +1377,51 @@
             super.close();
             update(e);
         }
     }
 
+    // Output stream returned when writing "deflated" entries into memory,
+    // to enable eager (possibly parallel) deflation and reduce memory required.
+    private class DeflatingByteArrayEntryOutputStream extends DeflaterOutputStream {
+        private Entry e;
+        private CRC32 crc;
+        private boolean isClosed;
+
+        DeflatingByteArrayEntryOutputStream(Entry e, ByteArrayOutputStream os) throws IOException {
+            super(os, getDeflater());
+            this.e = Objects.requireNonNull(e, "Zip entry is null");
+            this.crc = new CRC32();
+        }
+
+        @Override
+        public synchronized void write(int b) throws IOException {
+            super.write(b);
+            crc.update(b);
+        }
+
+        @Override
+        public synchronized void write(byte b[], int off, int len)
+                throws IOException {
+            super.write(b, off, len);
+            crc.update(b, off, len);
+        }
+
+        @Override
+        public synchronized void close() throws IOException {
+            if (isClosed)
+                return;
+            isClosed = true;
+            finish();
+            e.size  = def.getBytesRead();
+            e.csize = def.getBytesWritten();
+            e.bytes = ((ByteArrayOutputStream)out).toByteArray();
+            e.crc = crc.getValue();
+            releaseDeflater(def);
+            update(e);
+        }
+    }
+
     // Wrapper output stream class to write out a "stored" entry.
     // (1) this class does not close the underlying out stream when
     //     being closed.
     // (2) no need to be "synchronized", only used by sync()
     private class EntryOutputStreamCRC32 extends FilterOutputStream {
< prev index next >