(1)The extra field for ZIP64 (and any other type of extra field data block) has the format header ID (2 bytes) data size (2 bytes) data block The "data size" is the "size of data following", which does NOT inlclude the 2 + 2 bytes for the headerID + data size. We does it correct in ZipOutputStream.writeLOC/CEN, we do it correct in ZipFileSystem.writeLOC(). But unfortunately it appears we accidently included the 4 byte header (id + size) in ZipFileSystem.writeCEN(), as showed below if (csize >= ZIP64_MINVAL) { csize0 = ZIP64_MINVAL; elen64 += 8; // csize(8) } if (size >= ZIP64_MINVAL) { size0 = ZIP64_MINVAL; // size(8) elen64 += 8; } if (locoff >= ZIP64_MINVAL) { locoff0 = ZIP64_MINVAL; elen64 += 8; // offset(8) } if (elen64 != 0) elen64 += 4; // header and data sz 4 bytes ... if (elen64 != 0) { writeShort(os, EXTID_ZIP64);// Zip64 extra writeShort(os, elen64); // size of "this" extra block if (size0 == ZIP64_MINVAL) writeLong(os, size); if (csize0 == ZIP64_MINVAL) writeLong(os, csize); if (locoff0 == ZIP64_MINVAL) writeLong(os, locoff); } (2) ZipFileSystem.sync() OutputStream os = Files.newOutputStream(tmpFile, WRITE); It appears we are not wrapping the "os" with a BufferedOutputSteam, which might slow down the sync() when writing loc and cen tables, especially if we have lots of entries in the archive.
|