< 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 >