Come disimballare i file in modo programmato in Android?

Ho bisogno di un piccolo frammento di codice che estrae alcuni file da un dato file zip e fornisce i file separati in base al formato che erano nel file compresso. Inserisci la tua conoscenza e aiutami.

  • Come scorrere a livello di programmazione uno ScrollView in basso
  • Esempio conciso di caricamento di file tramite Java lib Apache Commons
  • Imansible eseguire il test di JUnit 4 nel progetto Android Eclipse
  • Issue BaseAdapter e Picasso
  • Come testare Android per pagare App in India
  • Canvas di Android non ha tracciato il path quando il punto del path è fuori visualizzazione
  • 11 Solutions collect form web for “Come disimballare i file in modo programmato in Android?”

    Aveva la versione di peno ottimizzata un po '. L'aumento delle performance è percepibile.

    private boolean unpackZip(String path, String zipname) { InputStream is; ZipInputStream zis; try { String filename; is = new FileInputStream(path + zipname); zis = new ZipInputStream(new BufferedInputStream(is)); ZipEntry ze; byte[] buffer = new byte[1024]; int count; while ((ze = zis.getNextEntry()) != null) { // zapis do souboru filename = ze.getName(); // Need to create directories if not exists, or // it will generate an Exception... if (ze.isDirectory()) { File fmd = new File(path + filename); fmd.mkdirs(); continue; } FileOutputStream fout = new FileOutputStream(path + filename); // cteni zipu a zapis while ((count = zis.read(buffer)) != -1) { fout.write(buffer, 0, count); } fout.close(); zis.closeEntry(); } zis.close(); } catch(IOException e) { e.printStackTrace(); return false; } return true; } 

    Sulla base della risposta di Vasily Sochinsky un po 'tweaked e con una piccola correzione:

     public static void unzip(File zipFile, File targetDirectory) throws IOException { ZipInputStream zis = new ZipInputStream( new BufferedInputStream(new FileInputStream(zipFile))); try { ZipEntry ze; int count; byte[] buffer = new byte[8192]; while ((ze = zis.getNextEntry()) != null) { File file = new File(targetDirectory, ze.getName()); File dir = ze.isDirectory() ? file : file.getParentFile(); if (!dir.isDirectory() && !dir.mkdirs()) throw new FileNotFoundException("Failed to ensure directory: " + dir.getAbsolutePath()); if (ze.isDirectory()) continue; FileOutputStream fout = new FileOutputStream(file); try { while ((count = zis.read(buffer)) != -1) fout.write(buffer, 0, count); } finally { fout.close(); } /* if time should be restored as well long time = ze.getTime(); if (time > 0) file.setLastModified(time); */ } } finally { zis.close(); } } 

    Differenze notevoli

    • public static – questo è un metodo di utilità statica che può essere dovunque.
    • 2 Parametri di File perché String sono: / per i file e non si potrebbe specificare where deve essere estratto il file zip prima. Anche il path + filename concatenamento dei path + filename > https://stackoverflow.com/a/412495/995891
    • throws – perché il ritardo in ritardo – aggiunga una prova di cattura se davvero non è interessato a loro.
    • effettivamente assicura che le directory richieste esistano in tutti i casi. Non tutte le zip contiene tutte le voci di directory richieste in anticipo rispetto alle voci di file. Questo aveva 2 possibili bug:
      • se la zip contiene una directory vuota e invece della directory risultante c'è un file esistente, questo è stato ignorato. Il valore restituito di mkdirs() è importnte.
      • potrebbe bloccarsi nei file zip che non contengono directory.
    • maggiore dimensione del buffer di scrittura, questo dovrebbe migliorare un po 'le performance. L'archiviazione è di solito in blocchi di 4k e la scrittura in blocchi più piccoli è di solito più lento del necessario.
    • utilizza la magia di finally per prevenire perdite di risorse.

    Così

     unzip(new File("/sdcard/pictures.zip"), new File("/sdcard")); 

    dovrebbe fare l'equivalente dell'originale

     unpackZip("/sdcard/", "pictures.zip") 

    Questo è il mio metodo di unzip, che uso:

     private boolean unpackZip(String path, String zipname) { InputStream is; ZipInputStream zis; try { is = new FileInputStream(path + zipname); zis = new ZipInputStream(new BufferedInputStream(is)); ZipEntry ze; while((ze = zis.getNextEntry()) != null) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int count; String filename = ze.getName(); FileOutputStream fout = new FileOutputStream(path + filename); // reading and writing while((count = zis.read(buffer)) != -1) { baos.write(buffer, 0, count); byte[] bytes = baos.toByteArray(); fout.write(bytes); baos.reset(); } fout.close(); zis.closeEntry(); } zis.close(); } catch(IOException e) { e.printStackTrace(); return false; } return true; } 

    Android ha build-in Java API. Controlla il pacchetto java.util.zip .

    La class ZipInputStream è quello che dovresti esaminare. Leggete ZipEntry dal ZipInputStream e scaricatelo in file system / folder. Controlla l' esempio simile per comprimere il file zip .

    Mentre le risposte che sono già qui funzionano bene, ho scoperto che erano leggermente più lenti di quanto avevo sperato. Invece ho usato zip4j , che penso sia la soluzione migliore per la sua velocità. Inoltre ha permesso diverse opzioni per la quantità di compressione, che ho trovato utile.

    UPDATE 2016 utilizza la seguente class

      package com.example.zip; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import android.util.Log; public class DecompressFast { private String _zipFile; private String _location; public DecompressFast(String zipFile, String location) { _zipFile = zipFile; _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()); BufferedOutputStream bufout = new BufferedOutputStream(fout); byte[] buffer = new byte[1024]; int read = 0; while ((read = zin.read(buffer)) != -1) { bufout.write(buffer, 0, read); } bufout.close(); zin.closeEntry(); fout.close(); } } zin.close(); Log.d("Unzip", "Unzipping complete. path : " +_location ); } catch(Exception e) { Log.e("Decompress", "unzip", e); Log.d("Unzip", "Unzipping failed"); } } private void _dirChecker(String dir) { File f = new File(_location + dir); if(!f.isDirectory()) { f.mkdirs(); } } } 

    Come usare

      String zipFile = Environment.getExternalStorageDirectory() + "/the_raven.zip"; //your zip file location String unzipLocation = Environment.getExternalStorageDirectory() + "/unzippedtestNew/"; // destination folder location DecompressFast df= new DecompressFast(zipFile, unzipLocation); df.unzip(); 

    permessi

      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
     public class MainActivity extends Activity { private String LOG_TAG = MainActivity.class.getSimpleName(); private File zipFile; private File destination; private TextView status; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); status = (TextView) findViewById(R.id.main_status); status.setGravity(Gravity.CENTER); if ( initialize() ) { zipFile = new File(destination, "BlueBoxnew.zip"); try { Unzipper.unzip(zipFile, destination); status.setText("Extracted to \n"+destination.getAbsolutePath()); } catch (ZipException e) { Log.e(LOG_TAG, e.getMessage()); } catch (IOException e) { Log.e(LOG_TAG, e.getMessage()); } } else { status.setText("Unable to initialize sd card."); } } public boolean initialize() { boolean result = false; File sdCard = new File(Environment.getExternalStorageDirectory()+"/zip/"); //File sdCard = Environment.getExternalStorageDirectory(); if ( sdCard != null ) { destination = sdCard; if ( !destination.exists() ) { if ( destination.mkdir() ) { result = true; } } else { result = true; } } return result; } } 

    -> Classe Helper (Unzipper.java)

      import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipInputStream; import android.util.Log; public class Unzipper { private static String LOG_TAG = Unzipper.class.getSimpleName(); public static void unzip(final File file, final File destination) throws ZipException, IOException { new Thread() { public void run() { long START_TIME = System.currentTimeMillis(); long FINISH_TIME = 0; long ELAPSED_TIME = 0; try { ZipInputStream zin = new ZipInputStream(new FileInputStream(file)); String workingDir = destination.getAbsolutePath()+"/"; byte buffer[] = new byte[4096]; int bytesRead; ZipEntry entry = null; while ((entry = zin.getNextEntry()) != null) { if (entry.isDirectory()) { File dir = new File(workingDir, entry.getName()); if (!dir.exists()) { dir.mkdir(); } Log.i(LOG_TAG, "[DIR] "+entry.getName()); } else { FileOutputStream fos = new FileOutputStream(workingDir + entry.getName()); while ((bytesRead = zin.read(buffer)) != -1) { fos.write(buffer, 0, bytesRead); } fos.close(); Log.i(LOG_TAG, "[FILE] "+entry.getName()); } } zin.close(); FINISH_TIME = System.currentTimeMillis(); ELAPSED_TIME = FINISH_TIME - START_TIME; Log.i(LOG_TAG, "COMPLETED in "+(ELAPSED_TIME/1000)+" seconds."); } catch (Exception e) { Log.e(LOG_TAG, "FAILED"); } }; }.start(); } } 

    -> layout xml (activity_main.xml):

     <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <TextView android:id="@+id/main_status" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="@string/hello_world" /> </RelativeLayout> 

    -> permesso in file Menifest:

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

    Secondo la risposta @zapl, Annulla con il rapporto di avanzamento:

     public interface UnzipFile_Progress { void Progress(int percent, String FileName); } // unzip(new File("/sdcard/pictures.zip"), new File("/sdcard")); public static void UnzipFile(File zipFile, File targetDirectory, UnzipFile_Progress progress) throws IOException, FileNotFoundException { long total_len = zipFile.length(); long total_installed_len = 0; ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile))); try { ZipEntry ze; int count; byte[] buffer = new byte[1024]; while ((ze = zis.getNextEntry()) != null) { if (progress != null) { total_installed_len += ze.getCompressedSize(); String file_name = ze.getName(); int percent = (int)(total_installed_len * 100 / total_len); progress.Progress(percent, file_name); } File file = new File(targetDirectory, ze.getName()); File dir = ze.isDirectory() ? file : file.getParentFile(); if (!dir.isDirectory() && !dir.mkdirs()) throw new FileNotFoundException("Failed to ensure directory: " + dir.getAbsolutePath()); if (ze.isDirectory()) continue; FileOutputStream fout = new FileOutputStream(file); try { while ((count = zis.read(buffer)) != -1) fout.write(buffer, 0, count); } finally { fout.close(); } // if time should be restored as well long time = ze.getTime(); if (time > 0) file.setLastModified(time); } } finally { zis.close(); } } 

    Ecco un ZipFileIterator (come un java Iterator, ma per file zip):

     package ch.epfl.bbp.io; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Iterator; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public class ZipFileIterator implements Iterator<File> { private byte[] buffer = new byte[1024]; private FileInputStream is; private ZipInputStream zis; private ZipEntry ze; public ZipFileIterator(File file) throws FileNotFoundException { is = new FileInputStream(file); zis = new ZipInputStream(new BufferedInputStream(is)); } @Override public boolean hasNext() { try { return (ze = zis.getNextEntry()) != null; } catch (IOException e) { e.printStackTrace(); } return false; } @Override public File next() { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); int count; String filename = ze.getName(); File tmpFile = File.createTempFile(filename, "tmp"); tmpFile.deleteOnExit();// TODO make it configurable FileOutputStream fout = new FileOutputStream(tmpFile); while ((count = zis.read(buffer)) != -1) { baos.write(buffer, 0, count); byte[] bytes = baos.toByteArray(); fout.write(bytes); baos.reset(); } fout.close(); zis.closeEntry(); return tmpFile; } catch (Exception e) { throw new RuntimeException(e); } } @Override public void remove() { throw new RuntimeException("not implemented"); } public void close() { try { zis.close(); is.close(); } catch (IOException e) {// nope } } } 

    Esempio minimo che ho usato per estrarre un file specifico dal mio zipfile nella mia cartella di cache delle applicazioni. Ho quindi letto il file manifesto utilizzando un metodo diverso.

     private void unzipUpdateToCache() { ZipInputStream zipIs = new ZipInputStream(context.getResources().openRawResource(R.raw.update)); ZipEntry ze = null; try { while ((ze = zipIs.getNextEntry()) != null) { if (ze.getName().equals("update/manifest.json")) { FileOutputStream fout = new FileOutputStream(context.getCacheDir().getAbsolutePath() + "/manifest.json"); byte[] buffer = new byte[1024]; int length = 0; while ((length = zipIs.read(buffer))>0) { fout.write(buffer, 0, length); } zipIs .closeEntry(); fout.close(); } } zipIs .close(); } catch (IOException e) { e.printStackTrace(); } } 

    Utilizza questa libreria.

    aggiungere questo file jar nella cartella di app di app.

    controllare l'importzione come tale

     import net.lingala.zip4j.core.ZipFile; import net.lingala.zip4j.exception.ZipException; import net.lingala.zip4j.model.FileHeader; 

    utilizzare il metodo seguente come questo

     unzip("/sdcard/file.zip","/sdcard/unzipFolder") public static void unzip(String Filepath, String DestinationFolderPath) { try { ZipFile zipFile = new ZipFile(Filepath); List<FileHeader> fileHeaders = zipFile.getFileHeaders(); for(FileHeader fileHeader : fileHeaders) { String fileName = fileHeader.getFileName(); if (fileName.contains("\\")) { fileName=fileName.replace("\\","\\\\"); String[] Folders=fileName.split("\\\\"); StringBuilder newFilepath=new StringBuilder(); newFilepath.append(DestinationFolderPath); for (int i=0;i&lt; Folders.length-1;i++){ newFilepath.append(File.separator); newFilepath.append(Folders[i]); } zipFile.extractFile(fileHeader, newFilepath.toString(),null,Folders[Folders.length-1]); }else { zipFile.extractFile(fileHeader,DestinationFolderPath); } } } catch (ZipException e) { e.printStackTrace(); } } 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.