Android - 解压缩文件夹?
Posted
技术标签:
【中文标题】Android - 解压缩文件夹?【英文标题】:Android - Unzip a folder? 【发布时间】:2011-02-17 11:38:04 【问题描述】:我的 SD 卡上有一个 zip 文件夹,如何解压缩该文件夹(在我的应用程序代码中)?
【问题讨论】:
我想你已经添加了访问外部存储的权限? 【参考方案1】:我正在使用 Beginner 方法的修改版本,它扩展了 AsyncTask 并可以更新主线程上的观察者。逐字节压缩非常慢,应该避免。相反,一种更有效的方法是将大量数据复制到输出流中。
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<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);
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);
被实现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)
回调。
【讨论】:
从哪里获得 IOUtils 以及如何安装它?IOUtils
是 Apache Commons IO 的一部分 commons.apache.org/proper/commons-io【参考方案2】:
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);
这对我有用,谢谢大家
【讨论】:
handleMessage() 中的情况 2 是什么?我没有看到任何 msg.what = 2。 它对我有用,但是如果我从服务器下载 zip 文件然后解压缩它,它会显示错误 java.util.zip.ZipException: EOCD not found,对它有任何想法 【参考方案3】:@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();
【讨论】:
以上是关于Android - 解压缩文件夹?的主要内容,如果未能解决你的问题,请参考以下文章