K-Zen
K-Zen

Reputation: 75

De-compressing a ZIP file using Java ZipFile class

I'm having a problem de-compressing a ZIP file using Java. The method is below.

The file structure is correct once the file is de-compressed, that means directories are fine inside the ZIP file, but the files output are of zero length.

I've checked the ZIP file, to see if the compression is correct, all correct there.

Please if anybody sees something I've missed ...

public static void unzip ( File zipfile, File directory ) throws IOException {
  ZipFile zip = new ZipFile ( zipfile );
  Enumeration<? extends ZipEntry> entries = zip.entries ();

  while ( entries.hasMoreElements () ) {
    ZipEntry entry = entries.nextElement ();
    File file = new File ( directory, entry.getName () );

    if ( entry.isDirectory () ) {
      file.mkdirs ();
    }
    else {
      file.getParentFile ().mkdirs ();

      ZipInputStream in = new ZipInputStream ( zip.getInputStream ( entry ) );
      OutputStream out = new FileOutputStream ( file );
      byte[] buffer = new byte[4096];
      int readed = 0;

      while ( ( readed = in.read ( buffer ) ) > 0 ) {
        out.write ( buffer, 0, readed );
        out.flush ();
      }

      out.close ();
      in.close ();
    }
  }

  zip.close ();
}

Something more... Apparently the method getInputStream ( entry ) is returning zero bytes, don't know why exactly.

Upvotes: 3

Views: 1430

Answers (2)

prunge
prunge

Reputation: 23238

ZipFile already decompresses an entry's data, there is no need to use a ZipInputStream as well.

Instead of:

ZipInputStream in = new ZipInputStream ( zip.getInputStream ( entry ) );

Use:

InputStream in = zip.getInputStream ( entry );

ZipInputStream can be used to uncompress ZIP files as well. The reason you are getting zero-length streams because with a ZipInputStream you need to call getNextEntry() to read the first file in the ZIP.

Upvotes: 2

JuanZe
JuanZe

Reputation: 8157

The following code works:

package so;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

public class TestZip {

    public static void main(String[] args) {
        String path = "C:" + File.separator + "tmp" + File.separator;
        String nom = "demo.zip";
        File zipfile = new File(path + nom);
        File directory = new File(path);
        TestZip m = new TestZip();
        try {
            m.unzip(zipfile, directory);
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
    }

    public static void unzip ( File zipfile, File directory ) throws IOException {
        System.out.println(zipfile.toString());
        System.out.println(directory.toString());
          ZipFile zip = new ZipFile (  zipfile );
          System.out.println("1");
          Enumeration<? extends ZipEntry> entries = zip.entries ();
          System.out.println("2");

          while ( entries.hasMoreElements () ) {
              System.out.println("3");
            ZipEntry entry = entries.nextElement ();
            File file = new File ( directory, entry.getName () );

            if ( entry.isDirectory () ) {
              file.mkdirs ();
            }
            else {
              file.getParentFile ().mkdirs ();

              ZipInputStream in = new ZipInputStream ( zip.getInputStream ( entry ) );
              OutputStream out = new FileOutputStream ( file );
              byte[] buffer = new byte[4096];
              int readed = 0;

              while ( ( readed = in.read ( buffer ) ) > 0 ) {
                out.write ( buffer, 0, readed );
                out.flush ();
              }

              out.close ();
              in.close ();
            }
          }

          zip.close ();
        }


}

So I think the problem is with the parameters you're passing. Create the argument "zipfile" with "new File(complete_path + filename)". If you just create with the filename it doesn't work.

Upvotes: -1

Related Questions