ZipInputStream getNextEntry имеет значение null при извлечении ZIP-файлов - PullRequest
4 голосов
/ 27 сентября 2011

Я пытаюсь извлечь файлы .zip и использую этот код:

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();

но проблема в том, что при отладке, когда код достигает части while (! = Null), zin.getNextEntry () всегда имеет значение null, поэтому ничего не извлекается ..
Размер файла .zip составляет 150 КБ. Как это исправить?

.zip существует

Код, который я использую для .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();

Ответы [ 5 ]

6 голосов
/ 22 июня 2012

Возможно, вы столкнулись со следующей проблемой, которая возникает при чтении zip-файлов с использованием ZipInputStream: Zip-файлы содержат записи и дополнительную информацию о структуре в последовательности. Кроме того, они содержат реестр всех записей в самом конце (!) Файла. Только этот реестр предоставляет полную информацию о правильной структуре файла zip. Следовательно, чтение zip-файла в последовательности с использованием потока иногда приводит к «предположению», что может привести к сбою. Это общая проблема всех реализаций zip, не только для java.util.zip. Лучше всего использовать ZipFile, который определяет структуру из реестра в конце файла. Возможно, вы захотите прочитать http://commons.apache.org/compress/zip.html,, который расскажет немного подробнее.

3 голосов
/ 29 сентября 2011

Если Zip находится в том же каталоге, что и этот точный источник с именем «91.zip», он работает просто отлично.

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. чтоязык в этом MP3, арабский?
  2. Мне пришлось изменить источник, чтобы он компилировался.
  3. Я использовал конструктор File, который принимает два аргумента String, чтобы вставитьисправить разделитель автоматически.
1 голос
/ 27 ноября 2013

Попробуйте этот код: -

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;

    }
0 голосов
/ 27 сентября 2011

Мне кажется, этот код работает правильно.

Вы уверены, что ваш zip-файл является действительным zip-файлом? Если файл не существует или недоступен для чтения, вы получите исключение FileNotFoundException, но если файл пустой или не является допустимым файлом zip, вы получите ze == null.

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

Указанный вами zip-файл не является допустимым zip-файлом. Размер записи 4294967295

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

Это дает:

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)

Попробуйте свой код с действительным zip-файлом.

0 голосов
/ 27 сентября 2011

Этот код отлично работает для меня.Возможно, вам нужно проверить, что строка zipFile действительна?

    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();

выдал правильные результаты для zip-файла 3.3Mb.

...