Android studio unzip file

Работа с архивами Zip и 7z

В мобильной разработке бывает потребность сделать приложение для работы без интернета. Например, словарь или справочник, который будет использоваться в суровых полевых условиях. Тогда для работы приложения нужно единожды выкачать архив с данными и сохранить его у себя. Сделать это можно посредством запроса в сеть, но так же можно зашить архив с данными внутрь приложения.

Согласно требованиям Google Play, apk-файл приложения должен быть не более 50 МБ, так же можно прикрепить два файла дополнения .obb по 2 гигабайта. Механизм простой, но сложный при эксплуатации, поэтому лучше всего уложиться в 50 МБ и возрадоваться. И в этом нам помогут целых два архивных формата Zip и 7z.

Давайте рассмотрим их работу на примере уже готового тестового приложения ZipExample.

Для тестов была создана sqlite база данных test_data.db. Она содержит 2 таблицы android_metadata — по традиции и my_test_data с миллионом строчек:

Размер полученного файла составляет 198 МБ.

Сделаем два архива test_data.zip (10.1 МБ) и test_data.7z (3.05 МБ).

Как очевидно, файлы БД sqlite очень хорошо сжимаются. По опыту могу сказать, что чем проще структура базы, тем лучше сжимается. Оба этих файла располагаются в папке assets и в процессе работы будут разархивированы.

Внешний вид программы представляет собой окно с текстом и двумя кнопками:

Вот метод распаковки zip архива:

Распаковывающим классом тут является ZipInputStream он входит в пакет java.util.zip, а тот в свою очередь в стандартную Android SDK и поэтому работает «из коробки» т.е. ничего отдельно закачивать не надо.

Вот метод распаковки 7z архива:

Сначала мы копируем файл архива из asserts , а потом разархивируем при помощи SevenZFile . Он находится в пакете org.apache.commons.compress.archivers.sevenz; и поэтому перед его использованием нужно прописать в build.gradle зависимость: compile ‘org.apache.commons:commons-compress:1.8’.
Android Stuodio сама скачает библиотеки, а если они устарели, то подскажет о наличии обновления.

Вот экран работающего приложения:

Размер отладочной версии приложения получился 6,8 МБ.
А вот его размер в устройстве после распаковки:

Внимание вопрос кто в черном ящике что в кеше?

В заключении хочу сказать, что распаковка архивов занимает продолжительное время и поэтому нельзя его делать в основном (UI) потоке. Это приведет к подвисанию интерфейса. Во избежание этого можно задействовать AsyncTask , а лучше фоновый сервис т.к. пользователь может не дождаться распаковки и выйти, а вы получите ошибку (правда если не поставите костылей в методе onPostExecute).

Читайте также:  Soul worker для андроид

Буду рад конструктивной критике в комментариях.

Источник

dhavaln / Decompress.java

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

package com.jumpbyte.webserver ;
import android.content.Context ;
import android.util.Log ;
import java.io.ByteArrayOutputStream ;
import java.io.File ;
import java.io.FileDescriptor ;
import java.io.FileInputStream ;
import java.io.FileOutputStream ;
import java.io.InputStream ;
import java.util.zip.ZipEntry ;
import java.util.zip.ZipInputStream ;
/**
*
* @author dhaval nagar
*/
public class Decompress <
private File _zipFile;
private InputStream _zipFileStream;
private Context context;
private static final String ROOT_LOCATION = » /sdcard » ;
private static final String TAG = » UNZIPUTIL » ;
public Decompress ( Context context , File zipFile ) <
_zipFile = zipFile;
this . context = context;
_dirChecker( » » );
>
public Decompress ( Context context , InputStream zipFile ) <
_zipFileStream = zipFile;
this . context = context;
_dirChecker( » » );
>
public void unzip () <
try <
Log . i( TAG , » Starting to unzip » );
InputStream fin = _zipFileStream;
if (fin == null ) <
fin = new FileInputStream (_zipFile);
>
ZipInputStream zin = new ZipInputStream (fin);
ZipEntry ze = null ;
while ((ze = zin . getNextEntry()) != null ) <
Log . v( TAG , » Unzipping » + ze . getName());
if (ze . isDirectory()) <
_dirChecker( ROOT_LOCATION + » / » + ze . getName());
> else <
FileOutputStream fout = new FileOutputStream ( new File ( ROOT_LOCATION , ze . getName()));
ByteArrayOutputStream baos = new ByteArrayOutputStream ();
byte [] buffer = new byte [ 1024 ];
int count;
// reading and writing
while ((count = zin . read(buffer)) != — 1 )
<
baos . write(buffer, 0 , count);
byte [] bytes = baos . toByteArray();
fout . write(bytes);
baos . reset();
>
fout . close();
zin . closeEntry();
>
>
zin . close();
Log . i( TAG , » Finished unzip » );
> catch ( Exception e) <
Log . e( TAG , » Unzip Error » , e);
>
>
private void _dirChecker ( String dir ) <
File f = new File (dir);
Log . i( TAG , » creating dir » + dir);
if (dir . length() >= 0 && ! f . isDirectory() ) <
f . mkdirs();
>
>
>

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

package com.jumpbyte.webserver ;
import android.app.Activity ;
import android.app.ProgressDialog ;
import android.content.Context ;
import android.os.AsyncTask ;
import android.util.Log ;
import java.io.BufferedInputStream ;
import java.io.File ;
import java.io.FileDescriptor ;
import java.io.FileOutputStream ;
import java.io.InputStream ;
import java.io.OutputStream ;
import java.net.URL ;
import java.net.URLConnection ;
/**
* Created by dhavalnagar on 03/02/15.
*/
public class DownloadFileAsync extends AsyncTask String , String , String > <
private static final String TAG = » DOWNLOADFILE » ;
public static final int DIALOG_DOWNLOAD_PROGRESS = 0 ;
private PostDownload callback;
private Context context;
private FileDescriptor fd;
private File file;
private String downloadLocation;
public DownloadFileAsync ( String downloadLocation , Context context , PostDownload callback ) <
this . context = context;
this . callback = callback;
this . downloadLocation = downloadLocation;
>
@Override
protected void onPreExecute () <
super . onPreExecute();
>
@Override
protected String doInBackground ( String . aurl ) <
int count;
try <
URL url = new URL (aurl[ 0 ]);
URLConnection connection = url . openConnection();
connection . connect();
int lenghtOfFile = connection . getContentLength();
Log . d( TAG , » Length of the file: » + lenghtOfFile);
InputStream input = new BufferedInputStream (url . openStream());
file = new File (downloadLocation);
FileOutputStream output = new FileOutputStream (file); // context.openFileOutput(«content.zip», Context.MODE_PRIVATE);
Log . d( TAG , » file saved at » + file . getAbsolutePath());
fd = output . getFD();
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 . flush();
output . close();
input . close();
> catch ( Exception e) <>
return null ;
>
protected void onProgressUpdate ( String . progress ) <
// Log.d(TAG,progress[0]);
>
@Override
protected void onPostExecute ( String unused ) <
if (callback != null ) callback . downloadDone(file);
>
public static interface PostDownload <
void downloadDone ( File fd );
>
>
Читайте также:  Пульт аэромышь для смарт тв андроид

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

@Override
public void onCreate( Bundle savedInstanceState) <
Button downloadContent = ( Button ) findViewById( R . id . downloadContent);
downloadContent . setOnClickListener( new View . OnClickListener () <
@Override
public void onClick ( View v ) <
downloadAndUnzipContent();
>
>);
>
private void downloadAndUnzipContent() <
String url = » https://github.com/NanoHttpd/nanohttpd/archive/master.zip » ;
DownloadFileAsync download = new DownloadFileAsync ( » /sdcard/content.zip » , this , new DownloadFileAsync . PostDownload () <
@Override
public void downloadDone ( File file ) <
Log . i( TAG , » file download completed » );
// check unzip file now
Decompress unzip = new Decompress ( Home . this , file);
unzip . unzip();
Log . i( TAG , » file unzip completed » );
>
>);
download . execute(url);
>

This comment has been minimized.

Copy link Quote reply

damilky commented Oct 7, 2019

E/UNZIPUTIL: Unzip Error
java.io.FileNotFoundException: /nanohttpd-master/.gitignore (No such file or directory)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:308)
at java.io.FileOutputStream.(FileOutputStream.java:238)
at java.io.FileOutputStream.(FileOutputStream.java:180)
at com.example.ipscansearchcve.Decompress.unzip(Decompress.java:56)
at com.example.ipscansearchcve.MainActivity$1.downloadDone(MainActivity.java:72)
at com.example.ipscansearchcve.DownloadFileAsync.onPostExecute(DownloadFileAsync.java:81)
at com.example.ipscansearchcve.DownloadFileAsync.onPostExecute(DownloadFileAsync.java:21)
at android.os.AsyncTask.finish(AsyncTask.java:695)
at android.os.AsyncTask.access$600(AsyncTask.java:180)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

I have this errors. plz help me.

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

Источник

How to Programmatically Zip and Unzip File in Android

This tutorial explains “How to Programmatically Zip and Unzip File in Android”. Zipping means writing (compress) data into zip files. Below code snippet will help you to zip and unzip files using a generic wrapper class that allows you to easily zip files in Android.

Читайте также:  Xamarin android save file

Why you need a Zip file?

  1. You couldn’t send multiple attachments using Intents to the Google Mail app. The quickest way around that was of course to compress all of the files into one (ZIP).
  2. For the applications that need to send multiple files to server, it is always easiest to create a zip file and send it across over network.

I have created both zip and unzip method inside a wrapper class called ZipManager . You may create the same way or you may like to use in your own way.

How to Zip files

Crete a sample android activity and add the following permission to application Mainfest.xml file. These persmissions are required to store data to your device storage.

You can use below code to create zip file. Just copy paste to make it work in your activity

BUFFER is used for limiting the buffer memory size while reading and writing data it to the zip stream

_files array holds all the file paths that you want to zip

zipFileName is the name of the zip file.

You can use this in your activity

You can get complete working eclipse project to end of this tutorial.

How to UnZip files

Now let us look into unzipping files. For unzipping you need to know the file path for .zip file and the path to the directory extract the files.

You can use this method in your activity

Download Complete Example

Here you can download complete eclipse project source code from GitHub.

Источник

Оцените статью