Android – распаковать папку?

У меня есть ZIP-папка на SD-карте, как я разархивировать папку (в моем коде приложения)?

Я использую модифицированную версию метода Beginner, которая расширяет AsyncTask и может обновлять Observers в основном streamе. Сжатие байтов байтом происходит очень медленно и его следует избегать. Вместо этого более эффективный подход заключается в копировании больших fragmentов данных в выходной stream.

package com.blarg.webviewscroller; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Observable; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.apache.commons.io.IOUtils; import android.os.AsyncTask; import android.util.Log; public class UnZipper extends Observable { private static final String TAG = "UnZip"; private String mFileName, mFilePath, mDestinationPath; public UnZipper (String fileName, String filePath, String destinationPath) { mFileName = fileName; mFilePath = filePath; mDestinationPath = destinationPath; } public String getFileName () { return mFileName; } public String getFilePath() { return mFilePath; } public String getDestinationPath () { return mDestinationPath; } public void unzip () { String fullPath = mFilePath + "/" + mFileName + ".zip"; Log.d(TAG, "unzipping " + mFileName + " to " + mDestinationPath); new UnZipTask().execute(fullPath, mDestinationPath); } private class UnZipTask extends AsyncTask { @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); } } catch (Exception e) { Log.e(TAG, "Error while extracting file " + archive, e); return false; } return true; } @Override protected void onPostExecute(Boolean result) { setChanged(); notifyObservers(); } 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(TAG, "Extracting: " + entry); BufferedInputStream inputStream = new BufferedInputStream(zipfile.getInputStream(entry)); BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile)); try { IOUtils.copy(inputStream, outputStream); } finally { outputStream.close(); inputStream.close(); } } private void createDir(File dir) { if (dir.exists()) { return; } Log.v(TAG, "Creating dir " + dir.getName()); if (!dir.mkdirs()) { throw new RuntimeException("Can not create dir " + dir); } } } } 

Он используется classом, который реализует Observer , например:

 private void unzipWebFile(String filename) { String unzipLocation = getExternalFilesDir(null) + "/unzipped"; String filePath = Environment.getExternalStorageDirectory().toString(); UnZipper unzipper = new UnZipper(filename, filePath, unzipLocation); unzipper.addObserver(this); unzipper.unzip(); } 

После завершения распаковки ваш наблюдатель получит обратный вызов update(Observable observable, Object data) .

 static Handler myHandler; ProgressDialog myProgress; public void unzipFile(File zipfile) { myProgress = ProgressDialog.show(getContext(), "Extract Zip", "Extracting Files...", true, false); File zipFile = zipfile; String directory = null; directory = zipFile.getParent(); directory = directory + "/"; myHandler = new Handler() { @Override public void handleMessage(Message msg) { // process incoming messages here switch (msg.what) { case 0: // update progress bar myProgress.setMessage("" + (String) msg.obj); break; case 1: myProgress.cancel(); Toast toast = Toast.makeText(getContext(), "Zip extracted successfully", Toast.LENGTH_SHORT); toast.show(); provider.refresh(); break; case 2: myProgress.cancel(); break; } super.handleMessage(msg); } }; Thread workthread = new Thread(new UnZip(zipFile, directory)); workthread.start(); } public class UnZip implements Runnable { File archive; String outputDir; public UnZip(File ziparchive, String directory) { archive = ziparchive; outputDir = directory; } public void log(String log) { Log.v("unzip", log); } @SuppressWarnings("unchecked") public void run() { Message msg; try { ZipFile zipfile = new ZipFile(archive); for (Enumeration e = zipfile.entries(); e.hasMoreElements();) { ZipEntry entry = (ZipEntry) e.nextElement(); msg = new Message(); msg.what = 0; msg.obj = "Extracting " + entry.getName(); myHandler.sendMessage(msg); unzipEntry(zipfile, entry, outputDir); } } catch (Exception e) { log("Error while extracting file " + archive); } msg = new Message(); msg.what = 1; myHandler.sendMessage(msg); } @SuppressWarnings("unchecked") public void unzipArchive(File archive, String outputDir) { try { ZipFile zipfile = new ZipFile(archive); for (Enumeration e = zipfile.entries(); e.hasMoreElements();) { ZipEntry entry = (ZipEntry) e.nextElement(); unzipEntry(zipfile, entry, outputDir); } } catch (Exception e) { log("Error while extracting file " + archive); } } 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("Extracting: " + entry); BufferedInputStream inputStream = new BufferedInputStream(zipfile .getInputStream(entry)); BufferedOutputStream outputStream = new BufferedOutputStream( new FileOutputStream(outputFile)); try { IOUtils.copy(inputStream, outputStream); } finally { outputStream.close(); inputStream.close(); } } private void createDir(File dir) { log("Creating dir " + dir.getName()); if (!dir.mkdirs()) throw new RuntimeException("Can not create dir " + dir); } } 

Это то, что сработало для меня благодаря людям

просто «аддон» для @ rich.e ответ:

в doInBackground() после итерации через ZipEtries вы должны закрыть файл, потому что иногда вам нужно удалить файл после разархивирования его, и он выдает исключение, если файл не был закрыт:

 try { ZipFile zipfile = new ZipFile(archive); int entries = zipfile.size(); int total = 0; if(onZipListener != null) onZipListener.onUncompressStart(archive); for (Enumeration e = zipfile.entries(); e.hasMoreElements();) { ZipEntry entry = (ZipEntry) e.nextElement(); if(onZipListener != null) onZipListener.onUncompressProgress(archive, (int) (total++ * 100 / entries)); unzipEntry(zipfile, entry, path); } zipfile.close(); } catch (Exception e) { e.printStackTrace(); } 
Давайте будем гением компьютера.