Распаковка файлов программно в Android

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

И мой код здесь:

public void DownloadDatabase(String DownloadUrl, String fileName) {
    try {
        File root = android.os.Environment.getExternalStorageDirectory();
        File dir = new File(root.getAbsolutePath() + "/timy/databases");
        if(dir.exists() == false){
             dir.mkdirs();  
        }

        URL url = new URL("http://myexample.com/android/timy.zip");
        File file = new File(dir,fileName);

        long startTime = System.currentTimeMillis();
        Log.d("DownloadManager" , "download url:" +url);
        Log.d("DownloadManager" , "download file name:" + fileName);

        URLConnection uconn = url.openConnection();
        uconn.setConnectTimeout(TIMEOUT_SOCKET);

        InputStream is = uconn.getInputStream();

        ZipInputStream zipinstream = new ZipInputStream(new BufferedInputStream(is));
        ZipEntry zipEntry;

        while((zipEntry = zipinstream.getNextEntry()) != null){
            String zipEntryName = zipEntry.getName();
            File file1 = new File(file + zipEntryName);
            if(file1.exists()){

            }else{
                if(zipEntry.isDirectory()){
                    file1.mkdirs();
                }
            }
        }

        BufferedInputStream bufferinstream = new BufferedInputStream(is);

        ByteArrayBuffer baf = new ByteArrayBuffer(5000);
        int current = 0;
        while((current = bufferinstream.read()) != -1){
            baf.append((byte) current);
        }

        FileOutputStream fos = new FileOutputStream( file);
        fos.write(baf.toByteArray());
        fos.flush();
        fos.close();
        Log.d("DownloadManager" , "download ready in" + ((System.currentTimeMillis() - startTime)/1000) + "sec");
    }
    catch(IOException e) {
        Log.d("DownloadManager" , "Error:" + e);
        e.printStackTrace();
    }

}

И мой логарифм показывает ошибку. Просто на моем устройстве создается папка, и никакие файлы не загружаются с разархивированными файлами. Без использования метода inputZipStream моя заархивированная папка загружается и сохраняется на SD-карте. Когда я хочу распаковать его, этого не происходит.


person kumar Sudheer    schedule 22.04.2013    source источник


Ответы (3)


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

Пакет java.util.zip предоставляет следующие классы для извлечения файлов и каталогов из ZIP-архива:

ZipInputStream: это основной класс, который можно использовать для чтения zip-файла и извлечения файлов и каталогов (записей) внутри архива. Вот несколько важных применений этого класса: - чтение zip с помощью его конструктора ZipInputStream(FileInputStream) - чтение записей файлов и каталогов с помощью метода getNextEntry() - чтение двоичных данных текущей записи с помощью метода read(byte) - закрытие текущей записи с помощью метод closeEntry() - закрыть zip-файл с помощью метода close()

ZipEntry: этот класс представляет запись в zip-файле. Каждый файл или каталог представлен как объект ZipEntry. Его метод getName() возвращает строку, представляющую путь к файлу/каталогу. Путь имеет следующий вид: папка_1/подпапка_1/подпапка_2/…/подпапка_n/файл.расш.

Основываясь на пути ZipEntry, мы заново создаем структуру каталогов при извлечении zip-файла.

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

  public class UnzipUtil
  {
     private String zipFile;
     private String location;

  public UnzipUtil(String zipFile, String location)
  {
     this.zipFile = zipFile;
     this.location = location;

     dirChecker("");
  }

  public void unzip()
 {
   try
 {
      FileInputStream fin = new FileInputStream(zipFile);
      ZipInputStream zin = new ZipInputStream(fin);
      ZipEntry ze = null;
      while ((ze = zin.getNextEntry()) != null)
      {
       Log.v("Decompress", "Unzipping " + ze.getName());

if(ze.isDirectory())
{
 dirChecker(ze.getName());
}
else
{
 FileOutputStream fout = new FileOutputStream(location + ze.getName());     

 byte[] buffer = new byte[8192];
 int len;
 while ((len = zin.read(buffer)) != -1)
 {
  fout.write(buffer, 0, len);
 }
 fout.close();

 zin.closeEntry();

}

    }
      zin.close();
    }
     catch(Exception e)
     {
          Log.e("Decompress", "unzip", e);
     }

  }

   private void dirChecker(String dir)
   {
         File f = new File(location + dir);
         if(!f.isDirectory())
          {
            f.mkdirs();
          }
         }
    }

Основная активность.Класс:

       public class MainActivity extends Activity
        {
        private ProgressDialog mProgressDialog;

        String Url="http://hasmukh/hb.zip";
        String unzipLocation = Environment.getExternalStorageDirectory() + "/unzipFolder/";
        String StorezipFileLocation =Environment.getExternalStorageDirectory() +                       "/DownloadedZip"; 
       String DirectoryName=Environment.getExternalStorageDirectory() + "/unzipFolder/files/";

       @Override
       protected void onCreate(Bundle savedInstanceState)
       {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

           DownloadZipfile mew = new DownloadZipfile();
            mew.execute(url);

        }

        //-This is method is used for Download Zip file from server and store in Desire location.
        class DownloadZipfile extends AsyncTask<String, String, String>
         {
         String result ="";
          @Override
          protected void onPreExecute()
          {
            super.onPreExecute();
            mProgressDialog = new ProgressDialog(MainActivity.this);
            mProgressDialog.setMessage("Downloading...");
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            mProgressDialog.setCancelable(false);
            mProgressDialog.show();
            }

             @Override
             protected String doInBackground(String... aurl)
             {
              int count;

                    try
          {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
InputStream input = new BufferedInputStream(url.openStream());

OutputStream output = new FileOutputStream(StorezipFileLocation);

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

while ((count = input.read(data)) != -1)
{
 total += count;
 publishProgress(""+(int)((total*100)/lenghtOfFile));
 output.write(data, 0, count);
}
output.close();
input.close();
result = "true";

         } catch (Exception e) {

         result = "false";
         }
        return null;

       }
        protected void onProgressUpdate(String... progress)
        {
        Log.d("ANDRO_ASYNC",progress[0]);
        mProgressDialog.setProgress(Integer.parseInt(progress[0]));
        }

         @Override
         protected void onPostExecute(String unused)
         {
               mProgressDialog.dismiss();
               if(result.equalsIgnoreCase("true"))
         {
          try
             {
                unzip();
                   } catch (IOException e)
                   {
                 // TODO Auto-generated catch block
              e.printStackTrace();
              }
                 }
                     else
                   {

                   }
                       }
               }
          //This is the method for unzip file which is store your location. And unzip folder will                 store as per your desire location.



             public void unzip() throws IOException 
            {
            mProgressDialog = new ProgressDialog(MainActivity.this);
            mProgressDialog.setMessage("Please Wait...");
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            mProgressDialog.setCancelable(false);
            mProgressDialog.show();
            new UnZipTask().execute(StorezipFileLocation, DirectoryName);
              }


          private class UnZipTask extends AsyncTask<String, Void, Boolean> 
          {
          @SuppressWarnings("rawtypes")
          @Override
          protected Boolean doInBackground(String... params) 
          {
             String filePath = params[0];
             String destinationPath = params[1];

               File archive = new File(filePath);
                try 
                 {
                 ZipFile zipfile = new ZipFile(archive);
                 for (Enumeration e = zipfile.entries(); e.hasMoreElements();) 
                 {
                         ZipEntry entry = (ZipEntry) e.nextElement();
                         unzipEntry(zipfile, entry, destinationPath);
                    }


         UnzipUtil d = new UnzipUtil(StorezipFileLocation, DirectoryName); 
         d.unzip();

            } 
    catch (Exception e) 
         {
           return false;
         }

          return true;
       }

           @Override
           protected void onPostExecute(Boolean result) 
           {
                mProgressDialog.dismiss(); 

             }


            private void unzipEntry(ZipFile zipfile, ZipEntry entry,String outputDir) throws IOException 
         {

                  if (entry.isDirectory()) 
        {
                createDir(new File(outputDir, entry.getName()));
                return;
          }

           File outputFile = new File(outputDir, entry.getName());
           if (!outputFile.getParentFile().exists())
           {
              createDir(outputFile.getParentFile());
           }

           // Log.v("", "Extracting: " + entry);
          BufferedInputStream inputStream = new BufferedInputStream(zipfile.getInputStream(entry));
          BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile));

       try 
        {

         }
       finally 
         {
              outputStream.flush();
              outputStream.close();
              inputStream.close();
          }
           }

             private void createDir(File dir) 
             {
                if (dir.exists()) 
              {
                   return;
                  }
                    if (!dir.mkdirs()) 
                      {
                        throw new RuntimeException("Can not create dir " + dir);
               }
               }}
                 }

            Note: Do not forgot to add below  permission in android Manifest.xml file.

          <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" ></uses-permission>
      <uses-permission android:name="android.permission.INTERNET" />

Подробнее

person Roadies    schedule 10.09.2013
comment
@RathaKrishna я столкнулся с проблемой с обратной косой чертой, я получаю путь к файлу, например sdcard/temp/765\765.json, есть ли способ slove - person Ando Masahashi; 17.12.2014
comment
@Ando путь к файлу = путь к файлу.replace(\, /); - person Matthew Carpenter; 26.04.2017
comment
Прекрасно работает. Спасибо большое :) - person Anjana Silva; 03.08.2017
comment
Небольшое обновление, с новейшим Android разрешение файла было изменено, поэтому местоположение файла должно быть изменено, например, местоположение мультимедиа здесь developer.android.com/training/data-storage/manage-all-files - person Y00; 18.11.2020

Функция распаковки

public void unzip(String _zipFile, String _targetLocation) {

    //create target location folder if not exist 
    dirChecker(_targetLocatioan); 

    try { 
        FileInputStream fin = new FileInputStream(_zipFile);
        ZipInputStream zin = new ZipInputStream(fin);
        ZipEntry ze = null;
        while ((ze = zin.getNextEntry()) != null) {

            //create dir if required while unzipping 
            if (ze.isDirectory()) {
                dirChecker(ze.getName());
            } else { 
                FileOutputStream fout = new FileOutputStream(_targetLocation + ze.getName());
                for (int c = zin.read(); c != -1; c = zin.read()) {
                    fout.write(c);
                } 

                zin.closeEntry();
                fout.close();
            } 

        } 
        zin.close();
    } catch (Exception e) {
        System.out.println(e);
    } 
} 

Инициализация

ZipManager zipManager = new ZipManager();

zipManager.unzip(inputPath + inputFile, outputPath);
person Vivek Hirpara    schedule 12.03.2018
comment
Превосходная простота! Две настройки: дайте ему буфер и измените цикл ввода-вывода. Он будет работать как ад byte[] buff = new byte[4096], затем используйте zin.read(buff) и fout.write(buff, 0, 4096) Spin on a while (len = zin.read(buff) › 0) - person MarkDubya; 28.01.2020

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

person Ankit Dubey    schedule 01.12.2018
comment
Это только для JAR. Не вводите в заблуждение - person Ranjith Kumar; 04.05.2021