распаковать файл с помощью java

public void unZipFile(String zipFileLocation, String outputFolder) {
    logger.info("ZipFileLocation: "+zipFileLocation);
    logger.info("OutputLocation: "+outputFolder);

    File dir = new File(outputFolder);
    // create output directory if it doesn't exist
    if(!dir.exists()) dir.mkdirs();
    FileInputStream fis;
    //buffer for read and write data to file
    byte[] buffer = new byte[1024];
    try {
        fis = new FileInputStream(zipFileLocation);
        ZipInputStream zis = new ZipInputStream(fis);
        ZipEntry ze = zis.getNextEntry();
        while(ze != null){
            String fileName = ze.getName();
            File newFile = new File(outputFolder + File.separator + fileName);
            System.out.println("Unzipping to "+newFile.getAbsolutePath());
            //create directories for sub directories in zip
            new File(newFile.getParent()).mkdirs();
            FileOutputStream fos = new FileOutputStream(newFile);
            int len;
            while ((len = zis.read(buffer)) > 0) {
                fos.write(buffer, 0, len);
            }
            fos.close();
            //close this ZipEntry
            zis.closeEntry();
            ze = zis.getNextEntry();
        }
        //close last ZipEntry
        zis.closeEntry();
        zis.close();
        fis.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Это код, который я использовал для распаковки папки в определенное место. я получаю следующее исключение после выполнения этого процесса. пожалуйста, совет, почему эта проблема возникает?

 java.util.zip.ZipException: invalid entry size (expected 3173388 but got 3173359 bytes)
 [java]     at java.util.zip.ZipInputStream.readEnd(ZipInputStream.java:403)
 [java]     at java.util.zip.ZipInputStream.read(ZipInputStream.java:195)
 [java]     at java.io.FilterInputStream.read(FilterInputStream.java:107)
 [java]     at com.shipxpress.irf.server.service.impl.IrfServiceImpl.unZipFile(IrfServiceImpl.java:1020)
 [java]     at com.shipxpress.irf.server.service.impl.IrfServiceImpl.executeFileTransferProcess(IrfServiceImpl.java:1310)
 [java]     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 [java]     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 [java]     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 [java]     at java.lang.reflect.Method.invoke(Method.java:606)

Очень ценю, если кто-нибудь может помочь мне решить эту проблему

Спасибо,


person nuwan.danushka    schedule 28.02.2017    source источник
comment
только что упомянул об исключении ниже, см. версию редактирования, спасибо   -  person nuwan.danushka    schedule 28.02.2017
comment
Я полагаю, что у вас есть поврежденный ZIP-файл. Можете ли вы разархивировать его из командной строки? Вы использовали FTP, не устанавливая двоичный режим?   -  person Stephen C    schedule 28.02.2017
comment
как установить бинарный режим?   -  person nuwan.danushka    schedule 28.02.2017
comment
Не могли бы вы попробовать с другим zip-файлом?   -  person ToYonos    schedule 28.02.2017
comment
Поможет ли это? stackoverflow.com/questions/13122212/   -  person Maddy    schedule 28.02.2017
comment
Это будет зависеть от того, какой инструмент вы используете для FTP-файла.   -  person Stephen C    schedule 28.02.2017
comment
Возможно, поврежден zip-файл   -  person rogerdpack    schedule 02.03.2018


Ответы (5)


Используйте эту библиотеку www.lingala.net/zip4j/

добавьте этот файл jar в папку lib приложения.

проверьте свой импорт таким образом

импортировать net.lingala.zip4j.core.ZipFile;

импортировать net.lingala.zip4j.exception.ZipException;

импортировать net.lingala.zip4j.model.FileHeader;

используйте следующий метод, подобный этому

распаковать("/sdcard/file.zip","/sdcard/unzipFolder")


  public static void unzip(String Filepath, String DestinationFolderPath) {

        try {
            ZipFile zipFile = new ZipFile(Filepath);
            List fileHeaders = zipFile.getFileHeaders();
            for(int i=0;i<fileHeaders.size();i++) {
                FileHeader  fileHeader=(FileHeader) fileHeaders.get(i);
                String fileName = fileHeader.getFileName();
                Log.d(TAG,fileName);
                if (fileName.contains("\\")) {
                    fileName=fileName.replace("\\","\\\\");
                    String[] Folders=fileName.split("\\\\");
                    StringBuilder newFilepath=new StringBuilder();
                    newFilepath.append(DestinationFolderPath);
                    for (int j=0;j<Folders.length-1;j++){
                        newFilepath.append(File.separator);
                        newFilepath.append(Folders[j]);
                    }
                    zipFile.extractFile(fileHeader, newFilepath.toString(),null,Folders[Folders.length-1]);
                }else {
                    zipFile.extractFile(fileHeader,DestinationFolderPath);
                }
            }
        } catch (ZipException e) {
            e.printStackTrace();
        }
    }

person KuLdip PaTel    schedule 28.04.2017

Я точно не знаю, почему в вашем случае это не работает (неверный zip-файл?), но я бы порекомендовал:

  • Во-первых, используйте API Java 7 java.nio.file.Path, который намного лучше, чем старый java.io.File.
  • Во-вторых, намного удобнее использовать Apache Commons Compress при работе со сжатыми файлами. Он намного более гибкий, так как может работать с форматами zip, bzip, 7zip, pack200 и другими.
  • Наконец, выполните операции .close() в блоке try... finally, чтобы избежать незакрытых потоков в случае исключения.
person Jerome L    schedule 28.02.2017

Я мог бы подумать об этих причинах:

  1. Файл может быть просто поврежден. Попробуйте открыть файл с помощью утилиты zip.
  2. Может быть проблема с кодировкой текстового файла.
  3. Файл необходимо читать/передавать в "бинарном" режиме.
  4. Может быть проблема с окончанием строки \n или \r\n
person P S M    schedule 28.02.2017

Вместо жесткого кодирования как

byte[] buffer = new byte[1024];

Попробуйте ниже.

byte[] buffer = new byte[(int) ze.getSize()];

Вы можете найти подробное руководство здесь.

https://www.youtube.com/watch?v=hzBlCnkhKog

person Varun A M    schedule 26.09.2017

У меня была аналогичная проблема, и я модифицировал код, чтобы он работал, оказалось, что код не различает файл и папку, и это та проверка, которую я добавил.

    public static void unzipFile(String zipFilePath, String destDir)
    {
        File dir = new File(destDir);
        // create output directory if it doesn't exist
        if (!dir.exists())
            dir.mkdirs();
        FileInputStream fis;
        // buffer for read and write data to file
        byte[] buffer = new byte[1024];
        try
        {
            fis = new FileInputStream(zipFilePath);
            ZipInputStream zis = new ZipInputStream(fis);
            ZipEntry ze = zis.getNextEntry();
            while (ze != null)
            {
                try
                {
                    String fileName = ze.getName();
                    File newFile = new File(destDir + File.separator + fileName);
                    System.out.println("Unzipping to " + newFile.getAbsolutePath());
                    // create directories for sub directories in zip
                    new File(newFile.getParent()).mkdirs();
                    if(ze.isDirectory()) // check if this is a diectory or file
                    {
                        newFile.mkdirs();
                    }
                    else
                    {
                        FileOutputStream fos = new FileOutputStream(newFile);
                        int len;
                        while ((len = zis.read(buffer)) > 0)
                        {
                            fos.write(buffer, 0, len);
                        }
                        fos.close();
                    }
                    // close this ZipEntry
                    zis.closeEntry();
                }
                catch(Exception e)
                {
                    System.err.println(e.getMessage());
                }
                ze = zis.getNextEntry();
            }
            // close last ZipEntry
            zis.closeEntry();
            zis.close();
            fis.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
person amralieg    schedule 14.10.2019