zip и распаковать в java

Я знаю, что это простая задача, но после изменения кода он перестал работать, и я не могу его вернуть! Я использую две функции для zip и unzip, хотя на самом деле это «jar» и «unjar», но это не должно иметь большого значения.

   public static void zipit(File[] infiles, JarOutputStream jos) throws Exception
   {
      zipit(infiles,"", jos);
   }

   public static void zipit(File[] infiles, String root, JarOutputStream jos) throws Exception
   {

      byte[] buffer = new byte[4096];

      for(int i=0; i<infiles.length; i++)
      {
         // recursive call for subfolders... temporary
         if(infiles[i].isDirectory())
         {
            zipit(infiles[i].listFiles(), infiles[i].getName() + "/", jos);
            continue;
         }

         // create string with absolute path
         String entryfile = root + infiles[i].getName();

         JarEntry entry = new JarEntry(entryfile);
         zos.putNextEntry(entry);

         FileInputStream fis = new FileInputStream(infiles[i]);

         int count;
         while((count = fis.read(buffer, 0, buffer.length)) != -1)
            zos.write(buffer, 0, count);
      }
   }

   public static void unzipit(File zipfile, File outputfolder) throws Exception
   {
      JarFile jar = new JarFile(zipfile);

      for(Enumeration entries = jar.entries(); entries.hasMoreElements(); )
      {
         JarEntry entry = (JarEntry) entries.nextElement();
         File unzipped = new File(outputfolder, entry.getName());
         if (entry.isDirectory() && !unzipped.exists())
         {
            unzipped.mkdirs();
            continue;
         }
         else if (!unzipped.getParentFile().exists())
            unzipped.getParentFile().mkdirs();

         FileOutputStream fos = new FileOutputStream(unzipped);
         InputStream in = jar.getInputStream(entry);

         byte[] buffer = new byte[4096];
         int count;
         while((count = in.read(buffer, 0, buffer.length)) != -1)
            fos.write(buffer, 0, count);
         fos.close();
      }
   }

Любая помощь / предложения?

Ошибка возникает при создании JarFile:

java.util.zip.ZipException: error in opening zip file
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:131)
    at java.util.jar.JarFile.<init>(JarFile.java:150)
    at java.util.jar.JarFile.<init>(JarFile.java:114)

person Oscar Wahltinez    schedule 27.12.2010    source источник
comment
Что вы изменили? Возможно, вам стоит подумать об использовании системы контроля версий.   -  person Greg Hewgill    schedule 28.12.2010
comment
Что именно не работает? Перестал работать мало   -  person unbeli    schedule 28.12.2010
comment
Я только тестировал функцию распаковки, но когда я пытаюсь распаковать что-то, ранее заархивированное с помощью функции zip, она выдаёт ошибку   -  person Oscar Wahltinez    schedule 28.12.2010
comment
возможный дубликат java.util.zip.ZipException: ошибка при открытии zip-файл   -  person zengr    schedule 28.12.2010
comment
посмотрев на вашу ссылку, кажется, что это другая проблема   -  person Oscar Wahltinez    schedule 28.12.2010


Ответы (2)


Я не знаю, ваша проблема в этом или нет, но обычно рекомендуется закрывать каждую запись в zip-архиве после того, как вы закончите писать.

См. ZipOutputStream.closeEntry() < / а>.

В коде, который вы показываете, самая последняя запись в почтовом индексе не будет закрыта. Вы также не показываете, где вы закрываете сам JarOutputStream. Это может привести к созданию недействительных zip-файлов, которые будут иметь ошибки при повторном считывании с использованием другого метода.

person James Branigan    schedule 27.12.2010
comment
это было мое предположение, но я тестировал его в основном, и даже когда я закрываю все потоки и zip-файлы, он не работает - person Oscar Wahltinez; 28.12.2010
comment
@omtinez, я рад, что ты решил свою проблему. Если закрытие потока было ответом, то обычный способ сделать что-то в StackOverflow - тоже принять правильный ответ в качестве решения. Повторная публикация фрагмента кода с изменением двух строк в качестве отдельного ответа - это не то, как обычно. - person James Branigan; 29.12.2010
comment
спасибо за понимание, я делаю это довольно очевидным, что я новичок в stackoverflow, но я постараюсь улучшить это - person Oscar Wahltinez; 02.01.2011

Каким-то образом у меня все заработало, по-видимому, это было связано с потоком ... Всем спасибо за помощь!

class zipper
{
     static byte[] buffer = new byte[4096];

     public static void unzip(File zipfile, File outputfolder)  throws Exception
     {
         JarFile zip = new JarFile(zipfile);

         Enumeration entries = zip.entries();
         while(entries.hasMoreElements())
         {
             JarEntry entry = (JarEntry) entries.nextElement();
             File unzipped = new File(outputfolder,entry.getName());

             if (entry.isDirectory() && !unzipped.exists())
             {
                 unzipped.mkdirs();
                 continue;
             }
             else if (!unzipped.getParentFile().exists())
                 unzipped.getParentFile().mkdirs();

             InputStream in = zip.getInputStream(entry);
             FileOutputStream fos = new FileOutputStream(unzipped);

             int count;
             while((count = in.read(buffer, 0, buffer.length)) != -1)
                 fos.write(buffer, 0, count);

             // clean up
             fos.close();
             in.close();
         }
   }

   public static void zip(File[] infiles, JarOutputStream jos) throws Exception
   {
       zip(infiles,"",jos);

       // clean up
       jos.flush();
       jos.close();
   }

   public static void zip(File[] infiles, String basefolder, JarOutputStream jos) throws Exception
   {
       for(int i=0; i<infiles.length; i++)
       {
           if(infiles[i].isDirectory())
           {
               // recursive call for directories
               zip(infiles[i].listFiles(), infiles[i].getName() + File.separator, jos);
               continue;
           }

           String filepath = basefolder + infiles[i].getName();
           JarEntry entry = new JarEntry(filepath);
           jos.putNextEntry(entry);

           FileInputStream fis = new FileInputStream(infiles[i]); // get stream

           int count;
           while((count = fis.read(buffer, 0, buffer.length)) != -1)
               jos.write(buffer, 0, count);
       }
   }
}
person Oscar Wahltinez    schedule 28.12.2010
comment
Спасибо, что разместили это, мне нужно было добраться до некоторых источников, набитых банкой. --дан - person Dan Doyon; 26.03.2012