From 1a4946cfd6c88cd17f387b99634ab859dbbea692 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Sun, 27 Jan 2013 09:58:16 +0000 Subject: [PATCH] improve performance when reading non zip64 zip files, merge from commons compress, based on patch by Robin Power git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@1439044 13f79535-47bb-0310-9956-ffa450edef68 --- CONTRIBUTORS | 1 + contributors.xml | 4 ++++ src/main/org/apache/tools/zip/ZipFile.java | 27 +++++++++++++++------- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index e6ab0018c..3e2ce0254 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -298,6 +298,7 @@ Robert Streich Robert Watkins Roberto Scaramuzzi Robin Green +Robin Power Robin Verduijn Rob Oxspring Rob van Oostrum diff --git a/contributors.xml b/contributors.xml index 91cf53265..543e200f7 100644 --- a/contributors.xml +++ b/contributors.xml @@ -1201,6 +1201,10 @@ Robin Green + + Robin + Power + Robin Verduijn diff --git a/src/main/org/apache/tools/zip/ZipFile.java b/src/main/org/apache/tools/zip/ZipFile.java index c10105062..0f09d0fd2 100644 --- a/src/main/org/apache/tools/zip/ZipFile.java +++ b/src/main/org/apache/tools/zip/ZipFile.java @@ -666,12 +666,14 @@ public class ZipFile { */ private void positionAtCentralDirectory() throws IOException { - boolean found = tryToLocateSignature(MIN_EOCD_SIZE + ZIP64_EOCDL_LENGTH, - MAX_EOCD_SIZE + ZIP64_EOCDL_LENGTH, - ZipOutputStream - .ZIP64_EOCD_LOC_SIG); + positionAtEndOfCentralDirectoryRecord(); + archive.seek(archive.getFilePointer() - ZIP64_EOCDL_LENGTH); + archive.readFully(WORD_BUF); + boolean found = Arrays.equals(ZipOutputStream.ZIP64_EOCD_LOC_SIG, + WORD_BUF); if (!found) { // not a ZIP64 archive + skipBytes(ZIP64_EOCDL_LENGTH - WORD); positionAtCentralDirectory32(); } else { positionAtCentralDirectory64(); @@ -686,7 +688,8 @@ public class ZipFile { */ private void positionAtCentralDirectory64() throws IOException { - skipBytes(ZIP64_EOCDL_LOCATOR_OFFSET); + skipBytes(ZIP64_EOCDL_LOCATOR_OFFSET + - WORD /* signature has already been read */); archive.readFully(DWORD_BUF); archive.seek(ZipEightByteInteger.getLongValue(DWORD_BUF)); archive.readFully(WORD_BUF); @@ -706,15 +709,23 @@ public class ZipFile { * record. */ private void positionAtCentralDirectory32() + throws IOException { + skipBytes(CFD_LOCATOR_OFFSET); + archive.readFully(WORD_BUF); + archive.seek(ZipLong.getValue(WORD_BUF)); + } + + /** + * Searches for the and positions the stream at the start of the + * "End of central dir record". + */ + private void positionAtEndOfCentralDirectoryRecord() throws IOException { boolean found = tryToLocateSignature(MIN_EOCD_SIZE, MAX_EOCD_SIZE, ZipOutputStream.EOCD_SIG); if (!found) { throw new ZipException("archive is not a ZIP archive"); } - skipBytes(CFD_LOCATOR_OFFSET); - archive.readFully(WORD_BUF); - archive.seek(ZipLong.getValue(WORD_BUF)); } /**