in src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java [1931:2029]
protected void writeZip64CentralDirectory() throws IOException {
if (zip64Mode == Zip64Mode.Never) {
return;
}
if (!hasUsedZip64 && shouldUseZip64EOCD()) {
// actually "will use"
hasUsedZip64 = true;
}
if (!hasUsedZip64) {
return;
}
long offset = streamCompressor.getTotalBytesWritten();
long diskNumberStart = 0L;
if (isSplitZip) {
// when creating a split zip, the offset of should be
// the offset to the corresponding segment disk
final ZipSplitOutputStream zipSplitOutputStream = (ZipSplitOutputStream)this.outputStream;
offset = zipSplitOutputStream.getCurrentSplitSegmentBytesWritten();
diskNumberStart = zipSplitOutputStream.getCurrentSplitSegmentIndex();
}
writeOut(ZIP64_EOCD_SIG);
// size of zip64 end of central directory, we don't have any variable length
// as we don't support the extensible data sector, yet
writeOut(ZipEightByteInteger
.getBytes(ZipConstants.SHORT /* version made by */
+ ZipConstants.SHORT /* version needed to extract */
+ ZipConstants.WORD /* disk number */
+ ZipConstants.WORD /* disk with central directory */
+ ZipConstants.DWORD /* number of entries in CD on this disk */
+ ZipConstants.DWORD /* total number of entries */
+ ZipConstants.DWORD /* size of CD */
+ (long) ZipConstants.DWORD /* offset of CD */
));
// version made by and version needed to extract
writeOut(ZipShort.getBytes(ZipConstants.ZIP64_MIN_VERSION));
writeOut(ZipShort.getBytes(ZipConstants.ZIP64_MIN_VERSION));
// number of this disk
int numberOfThisDisk = 0;
if (isSplitZip) {
numberOfThisDisk = ((ZipSplitOutputStream)this.outputStream).getCurrentSplitSegmentIndex();
}
writeOut(ZipLong.getBytes(numberOfThisDisk));
// disk number of the start of central directory
writeOut(ZipLong.getBytes(cdDiskNumberStart));
// total number of entries in the central directory on this disk
final int numOfEntriesOnThisDisk = isSplitZip
? numberOfCDInDiskData.getOrDefault(numberOfThisDisk, 0)
: entries.size();
final byte[] numOfEntriesOnThisDiskData = ZipEightByteInteger.getBytes(numOfEntriesOnThisDisk);
writeOut(numOfEntriesOnThisDiskData);
// number of entries
final byte[] num = ZipEightByteInteger.getBytes(entries.size());
writeOut(num);
// length and location of CD
writeOut(ZipEightByteInteger.getBytes(cdLength));
writeOut(ZipEightByteInteger.getBytes(cdOffset));
// no "zip64 extensible data sector" for now
if (isSplitZip) {
// based on the ZIP specification, the End Of Central Directory record and
// the Zip64 End Of Central Directory locator record must be on the same segment
final int zip64EOCDLOCLength = ZipConstants.WORD /* length of ZIP64_EOCD_LOC_SIG */
+ ZipConstants.WORD /* disk number of ZIP64_EOCD_SIG */
+ ZipConstants.DWORD /* offset of ZIP64_EOCD_SIG */
+ ZipConstants.WORD /* total number of disks */;
final long unsplittableContentSize = zip64EOCDLOCLength + eocdLength;
((ZipSplitOutputStream)this.outputStream).prepareToWriteUnsplittableContent(unsplittableContentSize);
}
// and now the "ZIP64 end of central directory locator"
writeOut(ZIP64_EOCD_LOC_SIG);
// disk number holding the ZIP64 EOCD record
writeOut(ZipLong.getBytes(diskNumberStart));
// relative offset of ZIP64 EOCD record
writeOut(ZipEightByteInteger.getBytes(offset));
// total number of disks
if (isSplitZip) {
// the Zip64 End Of Central Directory Locator and the End Of Central Directory must be
// in the same split disk, it means they must be located in the last disk
final int totalNumberOfDisks = ((ZipSplitOutputStream)this.outputStream).getCurrentSplitSegmentIndex() + 1;
writeOut(ZipLong.getBytes(totalNumberOfDisks));
} else {
writeOut(ONE);
}
}