Skip to content Skip to sidebar Skip to footer

Reading A Decrypted File Into A Zipinputstream Truncates First File Sometimes

I'm working on an e-reader app (using skyepub) that basically downloads encrypted books into the file system (and it saves is decryption key in the database), and when the user tri

Solution 1:

According to the docs, getSize() may return -1 if the size is unknown. This definitely happens in some zip files. In those cases, you'll need to read the entire entry in order to determine its uncompressed size.

Analysis

Red herring

First of all the whole encryption decryption thing was a red herring.. simply copying the same epub/zip file and reading it using the same code resulted in the same page.. so this is a problem with the zip file itself rather than the decryption of it

Zip documentation

As mentioned in the java doc, reading a zip file can actually return -1 if the content is unknown (which is exactly what's going on here).. as a matter of fact, we got the same zip file, unzipped it (on command line) then rezipped it with an increased compression level like so:

zip -9 -r filename.epub *

then we fed the same zip file to the existing code and it worked perfectly!

solution

So this is the final code that worked:

try {
        InputStreamstream= abjjadDb.getBookStream(bookEditionID);
        if( stream == null) returnnull;

        finalZipInputStreamzip=newZipInputStream(stream);

        ZipEntry entry;
        do {
            entry = zip.getNextEntry();
            if( entry == null) {
                zip.close();
                returnnull;
            }
        } while( !entry.getName().equals(zipEntryName));

        data.contentLength = entry.getSize();
        data.lastModified = entry.getTime();
        data.contentPath = contentPath;

        InputStreams= zip;
        if( data.contentLength == -1) {
            Log.e("demo",newObject(){}.getClass().getEnclosingMethod().getName()+":: entry \""+entry+"\" has contentLength -1, so we will work around");
            ByteArrayOutputStreambuffer=newByteArrayOutputStream();
            int nRead;
            // use buf to store data from the zip file entry in fixed sizebyte[] buf = newbyte[4096];
            while ((nRead = zip.read(buf)) != -1) {
                // dump that data into buffer, which is a growing buffer
                buffer.write(buf, 0, nRead);
            }
            buffer.flush();

            byte[] finalBuffer = buffer.toByteArray();
            Log.e("demo",newObject(){}.getClass().getEnclosingMethod().getName()+":: entry \""+entry+"\" final data length: "+finalBuffer.length);
            data.contentLength = finalBuffer.length;
            s = newByteArrayInputStream(finalBuffer);
        }
        finalInputStreamfinalStream= s;

and the logs give us this

getContentData:: entry "OEBPS/hayat-ghayr.html" has contentLength -1, so we will work around
getContentData:: entry "OEBPS/hayat-ghayr.html"final data length: 2378
getContentData:: entry "OEBPS/hayat-ghayr.html" has contentLength -1, so we will work around
getContentData:: entry "OEBPS/hayat-ghayr.html"final data length: 2378

interestingly.. that size makes an exact match with the actual content length of that file hayat-ghayr if we run this on the command line:

$ unzip -l b17c024e-89f1-42f7-a546-91d46610cedb.epub 
Archive:  b17c024e-89f1-42f7-a546-91d46610cedb.epub
  Length     Date   Time    Name
 --------    ----   ----    ----
       20  01-27-12 11:17   mimetype
     2378  04-20-12 10:12   OEBPS/hayat-ghayr.html
     6436  02-06-12 11:06   OEBPS/content.opf
   112579  01-27-12 11:25   OEBPS/images/978-614-425-313-7-hayat-ghayr-cover.png
   182575  01-27-12 11:25   OEBPS/images/978-614-425-313-7-hayat_fmt.png
     7757  01-27-12 11:21   OEBPS/template.css
     5643  01-27-12 11:18   OEBPS/hayat-ghayr-2.html
    20144  01-27-12 11:17   OEBPS/hayat-ghayr-1.html
    65543  01-27-12 11:17   OEBPS/hayat-ghayr-3.html
    59434  01-27-12 11:17   OEBPS/hayat-ghayr-4.html
    66768  01-27-12 11:17   OEBPS/hayat-ghayr-5.html
    49117  01-27-12 11:17   OEBPS/hayat-ghayr-6.html
    65346  01-27-12 11:17   OEBPS/hayat-ghayr-7.html
    74196  01-27-12 11:17   OEBPS/hayat-ghayr-8.html
    73998  01-27-12 11:17   OEBPS/hayat-ghayr-9.html
    61031  01-27-12 11:17   OEBPS/hayat-ghayr-10.html
    68297  01-27-12 11:17   OEBPS/hayat-ghayr-11.html
    72084  01-27-12 11:17   OEBPS/hayat-ghayr-12.html
     2386  01-27-12 11:17   OEBPS/hayat-ghayr-13.html
    61132  01-27-12 11:17   OEBPS/hayat-ghayr-14.html
    46320  01-27-12 11:17   OEBPS/hayat-ghayr-15.html
    32673  01-27-12 11:17   OEBPS/hayat-ghayr-16.html
    88584  01-27-12 11:17   OEBPS/hayat-ghayr-17.html
    56474  01-27-12 11:17   OEBPS/hayat-ghayr-18.html
    52840  01-27-12 11:17   OEBPS/hayat-ghayr-19.html
    80022  01-27-12 11:17   OEBPS/hayat-ghayr-20.html
    50781  01-27-12 11:17   OEBPS/hayat-ghayr-21.html
     2765  01-27-12 11:17   OEBPS/hayat-ghayr-22.html
      265  01-27-12 11:17   META-INF/container.xml
    54942  01-27-12 11:17   OEBPS/images/277.png
     5549  01-27-12 11:17   OEBPS/toc.ncx
     1072  03-23-12 13:28   iTunesMetadata.plist
 --------                   -------
  1529151                   32 files

Post a Comment for "Reading A Decrypted File Into A Zipinputstream Truncates First File Sometimes"