Android: Faster way to read/write a ZipInputStream?
Asked Answered
L

2

5

I am currently writing an application that reads a zip file in my assets folder which contains a bunch of images. I am using the ZipInputStream API to read the contents and then writing each file to my: Environment.getExternalStorageDirectory() directory. I have everything working but the first time the application is run writing the images to the storage directory is INCREDIBLY slow. It takes about about 5 minutes to write my images to disc. My code looks like this:

ZipEntry ze = null;
ZipInputStream zin = new ZipInputStream(getAssets().open("myFile.zip"));
String location = getExternalStorageDirectory().getAbsolutePath() + "/test/images/";

    //Loop through the zip file
    while ((ze = zin.getNextEntry()) != null) {
         File f = new File(location + ze.getName());
          //Doesn't exist? Create to avoid FileNotFoundException
          if(f.exists()) {
             f.createNewFile();
          }
          FileOutputStream fout = new FileOutputStream(f);
          //Read contents and then write to file
          for (c = zin.read(); c != -1; c = zin.read()) {
             fout.write(c);
          }             
    }
    fout.close();
    zin.close();

The process of reading the contents of the particular entry and then writing to it is VERY slow. I am assuming it is more to do with reading than writing. I've read that you can use a byte[] array buffer to speed up the process but this does not seem to work! I tried this but it only read part of the file...

    FileOutputStream fout = new FileOutputStream(f);
    byte[] buffer = new byte[(int)ze.getSize()];
     //Read contents and then write to file
      for (c = zin.read(buffer); c != -1; c = zin.read(buffer)) {
            fout.write(c);
      }             
  }

When I do that I only get about 600-800 bytes written. Is there a way to speed this up?? Have I implemented the buffer array incorrectly??

Laudianism answered 27/7, 2011 at 22:38 Comment(0)
L
12

I found a much better solution which implements the BuffererdOutputStream API. My solution looks like this:

   byte[] buffer = new byte[2048];

   FileOutputStream fout = new FileOutputStream(f);
   BufferedOutputStream bos = new BufferedOutputStream(fout, buffer.length);

   int size;

    while ((size = zin.read(buffer, 0, buffer.length)) != -1) {
            bos.write(buffer, 0, size);
        }
        //Close up shop..
        bos.flush();
        bos.close();

        fout.flush();
        fout.close();
        zin.closeEntry();

I managed to increase my load time from anywhere from an average of about 5 minutes to about 5 (depending on how many images are in the package). Hope this helps!

Laudianism answered 30/7, 2011 at 0:8 Comment(4)
THANKS! About 4 minutes took it before to unzip my 2 MB-sized File and is increased to 2 seconds. Very helpful.Haywood
Jack, your solution is awesome, but we don't need line: int c = 0;Slipway
This took my unzip process from an average of 5 seconds to under a second - perfect. Thanks!Erdah
Great answer! I was using the previously mentioned method and my process went from me getting so annoyed to killing to app, to being done in a couple of seconds. Thanks again!Malawi
A
0

Try use http://commons.apache.org/io/ like:

 InputStream in = new URL( "http://jakarta.apache.org" ).openStream();
 try {
   System.out.println( IOUtils.toString( in ) );
 } finally {
   IOUtils.closeQuietly(in);
 }
Abrahamabrahams answered 28/7, 2011 at 6:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.