5

I'm trying to extract .zip files and I'm using this code:

String zipFile = Path + FileName;

FileInputStream fin = new FileInputStream(zipFile);
ZipInputStream zin = new ZipInputStream(fin);

ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
    UnzipCounter++;
    if (ze.isDirectory()) {
        dirChecker(ze.getName());
    } else {
        FileOutputStream fout = new FileOutputStream(Path
                + ze.getName());
        while ((Unziplength = zin.read(Unzipbuffer)) > 0) {
            fout.write(Unzipbuffer, 0, Unziplength);                    
        }
        zin.closeEntry();
        fout.close();

    }
}
zin.close();

but the problem is that, while debugging, when the code reaches the while(!=null) part, the zin.getNextEntry() is always null so it doesnt extract anything..
The .zip file is 150kb.. How can I fix this?

The .zip exists

Code I use to dl the .zip:

URL=intent.getStringExtra("DownloadService_URL");
    FileName=intent.getStringExtra("DownloadService_FILENAME");
    Path=intent.getStringExtra("DownloadService_PATH");
     File PathChecker = new File(Path);
    try{

    if(!PathChecker.isDirectory())
        PathChecker.mkdirs();

    URL url = new URL(URL);
    URLConnection conexion = url.openConnection();

    conexion.connect();
    int lenghtOfFile = conexion.getContentLength();
    lenghtOfFile/=100;

    InputStream input = new BufferedInputStream(url.openStream());
    OutputStream output = new FileOutputStream(Path+FileName);

    byte data[] = new byte[1024];
    long total = 0;

    int count = 0;
    while ((count = input.read(data)) != -1) {
        output.write(data, 0, count);
        total += count;

        notification.setLatestEventInfo(context, contentTitle, "جاري تحميل ملف " + FileName + " " + (total/lenghtOfFile), contentIntent);
        mNotificationManager.notify(1, notification);
    }


    output.flush();
    output.close();
    input.close();
Omar
  • 7,835
  • 14
  • 62
  • 108

6 Answers6

7

You might have run into the following problem, which occurs, when reading zip files using a ZipInputStream: Zip files contain entries and additional structure information in a sequence. Furthermore, they contain a registry of all entries at the very end (!) of the file. Only this registry does provide full information about the correct zip file structure. Therefore, reading a zip file in a sequence, by using a stream, sometimes results in a "guess", which can fail. This is a common problem of all zip implementations, not only for java.util.zip. Better approach is to use ZipFile, which determines the structure from the registry at the end of the file. You might want to read http://commons.apache.org/compress/zip.html, which tells a little more details.

MikkoP
  • 4,864
  • 16
  • 58
  • 106
Harry
  • 71
  • 1
  • 2
4

If the Zip is placed in the same directory as this exact source, named "91.zip", it works just fine.

import java.io.*;
import java.util.zip.*;

class Unzip {
    public static void main(String[] args) throws Exception {
        String Path = ".";
        String FileName = "91.zip";
        File zipFile = new File(Path, FileName);

        FileInputStream fin = new FileInputStream(zipFile);
        ZipInputStream zin = new ZipInputStream(fin);

        ZipEntry ze = null;
        int UnzipCounter = 0;
        while ((ze = zin.getNextEntry()) != null) {
            UnzipCounter++;
            //if (ze.isDirectory()) {
            //  dirChecker(ze.getName());
            //} else {
                byte[] Unzipbuffer = new byte[(int) pow(2, 16)];
                FileOutputStream fout = new FileOutputStream(
                    new File(Path, ze.getName()));
                int Unziplength = 0;
                while ((Unziplength = zin.read(Unzipbuffer)) > 0) {
                    fout.write(Unzipbuffer, 0, Unziplength);
                }
                zin.closeEntry();
                fout.close();
            //}
        }
        zin.close();
    }
}

BTW

  1. what is the language in that MP3, Arabic?
  2. I had to alter the source to get it to compile.
  3. I used the File constructor that takes two String arguments, to insert the correct separator automatically.
Ria
  • 10,237
  • 3
  • 33
  • 60
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
1

Try this code:-

private boolean extractZip(String pathOfZip,String pathToExtract)
 {


        int BUFFER_SIZE = 1024;
        int size;
        byte[] buffer = new byte[BUFFER_SIZE];


        try {
            File f = new File(pathToExtract);
            if(!f.isDirectory()) {
                f.mkdirs();
            }
            ZipInputStream zin = new ZipInputStream(new BufferedInputStream(new FileInputStream(pathOfZip), BUFFER_SIZE));
            try {
                ZipEntry ze = null;
                while ((ze = zin.getNextEntry()) != null) {
                    String path = pathToExtract  +"/"+ ze.getName();

                    if (ze.isDirectory()) {
                        File unzipFile = new File(path);
                        if(!unzipFile.isDirectory()) {
                            unzipFile.mkdirs();
                        }
                    }
                    else {
                        FileOutputStream out = new FileOutputStream(path, false);
                        BufferedOutputStream fout = new BufferedOutputStream(out, BUFFER_SIZE);
                        try {
                            while ( (size = zin.read(buffer, 0, BUFFER_SIZE)) != -1 ) {
                                fout.write(buffer, 0, size);
                            }

                            zin.closeEntry();
                        }catch (Exception e) {
                            Log.e("Exception", "Unzip exception 1:" + e.toString());
                        }
                        finally {
                            fout.flush();
                            fout.close();
                        }
                    }
                }
            }catch (Exception e) {
                Log.e("Exception", "Unzip exception2 :" + e.toString());
            }
            finally {
                zin.close();
            }
            return true;
        }
        catch (Exception e) {
            Log.e("Exception", "Unzip exception :" + e.toString());
        }
        return false;

    }
Jagdish
  • 2,418
  • 4
  • 25
  • 51
0

I know it's late for answer but anyway .. I think the problem is in

if(!PathChecker.isDirectory())
    PathChecker.mkdirs();

it should be

if(!PathChecker.getParentFile().exists())
    PathChecker.getParentFile().mkdirs();
Abdo Wise
  • 11
  • 2
0

This code works fine for me. Perhaps you need to check that the zipFile String is valid?

    String zipFile = "C:/my.zip";

    FileInputStream fin = new FileInputStream(zipFile);
    ZipInputStream zin = new ZipInputStream(fin);

    ZipEntry ze = null;
    while ((ze = zin.getNextEntry()) != null) {
        System.out.println("got entry " + ze);
    }
    zin.close();

produced valid results on a 3.3Mb zip file.

Eric Lindauer
  • 1,813
  • 13
  • 19
0

This code seems to work correctly for me.

Are you sure that your zip file is a valid zip file? If the file does not exist or is not readable then you will get a FileNotFoundException, but if the file is empty or not a valid zip file, then you will get ze == null.

while ((ze = zin.getNextEntry()) != null) {

The zip that you specify isn't a valid zip file. The size of the entry is 4294967295

while ((ze = zin.getNextEntry()) != null) {
    System.out.println("ze=" + ze.getName() + " " + ze.getSize());
    UnzipCounter++;

This gives:

ze=595.mp3 4294967295
...
Exception in thread "main" java.util.zip.ZipException: invalid entry size (expected 4294967295 but got 341297 bytes)
    at java.util.zip.ZipInputStream.readEnd(ZipInputStream.java:386)
    at java.util.zip.ZipInputStream.read(ZipInputStream.java:156)
    at java.io.FilterInputStream.read(FilterInputStream.java:90)
    at uk.co.farwell.stackoverflow.ZipTest.main(ZipTest.java:29)

Try your code with a valid zip file.

Matthew Farwell
  • 60,889
  • 18
  • 128
  • 171
  • As you said the file obviously exists since it would throw the exception.. I just redownloaded the zip, opened with an Android app (FileExpert), and the .zip got extracted successfully! so the .zip works! – Omar Sep 27 '11 at 11:02
  • *"I just redownloaded the zip.."* 1) The net is a big place. Care to share an URL? 2) Java only understands some types of Zip compression. – Andrew Thompson Sep 27 '11 at 12:39
  • http://www.tinyurl.com/5udabdl .. I've edited the question with the code I used to dl the .zip .. I zipped the .zip files with a C# app I wrote – Omar Sep 27 '11 at 15:36
  • @AndrewThompson Did you try the .zip? Thanks. – Omar Sep 28 '11 at 15:29
  • @MatthewFarwell I tried with another zip I manually created and it worked.. I've posted the code I use in C#, can you see whats wrong there: http://stackoverflow.com/questions/7587207/is-the-code-im-using-to-make-zip-files-correct – Omar Sep 29 '11 at 07:19
  • If that is so, then your question has been answered, can you accept the answer please? Thanks. – Matthew Farwell Sep 29 '11 at 07:25