private static void processZAE(ZipArchiveEntry zae, ZipArchiveInputStream zipArchiveInputStream,
                                   ZipArchiveOutputStream outputStream) throws IOException {
        while (zae != null) {
            if (!zae.isDirectory() && zipArchiveInputStream.canReadEntryData(zae)) {
                //create a new ZAE and copy over only the name so that
                //if there is bad info (e.g. CRC) in brokenZip's zae, that
                //won't be propagated or cause an exception
                outputStream.putArchiveEntry(new ZipArchiveEntry(zae.getName()));
                //this will copy an incomplete stream...so there
                //could be truncation of the xml/contents, but the zip file
                //should be intact.
                boolean successfullyCopied = false;
                try {
                    IOUtils.copy(zipArchiveInputStream, outputStream);
                    successfullyCopied = true;
                } catch (IOException e) {
                    //this can hit a "truncated ZipFile" IOException
                }
                outputStream.flush();
                outputStream.closeArchiveEntry();
                if (!successfullyCopied) {
                    break;
                }
            }
            zae = zipArchiveInputStream.getNextEntry();
        }
    }
This streams the broken zip and rebuilds a new zip that
is at least a valid zip file.  The contents of the final stream
may be truncated, but the result should be a valid zip file.
<p>
This does nothing fancy to fix the underlying broken zip.
<p>
This will close the inputstream

@param brokenZip
@param salvagedZip
@param allowStoredEntries
@throws java.io.IOException
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/main/java/org/apache/tika/zip/utils/ZipSalvager.java