在 Android 应用程序中解压缩 sd 卡上的压缩文件
Posted
技术标签:
【中文标题】在 Android 应用程序中解压缩 sd 卡上的压缩文件【英文标题】:Unzip a zipped file on sd card in Android application 【发布时间】:2011-12-03 14:11:24 【问题描述】:我有一个压缩密码保护保存在 android 模拟器上的 sd 卡上的视频文件。现在我想通过代码解压缩 sd 卡上的视频文件。我怎样才能做到这一点?任何帮助或代码? 提前致谢
【问题讨论】:
google.com/search?q=android+unzip+file 这个问题已经被问过很多次了。它在 Java 库而不是 Android 库中。见这里:***.com/questions/3382996/… 看看来自 Android 开发者网站的 ZipInputStream:developer.android.com/reference/java/util/zip/ZipFile.html 这里是 Kotlin 解决方案 - ***.com/a/50990872/1162784 它使用文件扩展名。 How to unzip files programmatically in Android?的可能重复 【参考方案1】:import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
*
* @author jon
*/
public class Decompress
private String _zipFile;
private String _location;
public Decompress(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());
for (int c = zin.read(); c != -1; c = zin.read())
fout.write(c);
zin.closeEntry();
fout.close();
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();
在你的情况下::
String zipFilename = Environment.getExternalStorageDirectory() + "/files.zip";
String unzipLocation = Environment.getExternalStorageDirectory() + "/unzipped/";
Decompress d = new Decompress(zipFilename, unzipLocation);
d.unzip();
【讨论】:
Divyesh 感谢您的回复。但我仍然很困惑,因为我的压缩文件受密码保护,所以我将如何匹配该密码以输入文件? 只是对您答案的补充,实际的条目读取和文件写入可以分块完成,以获得更高的性能,而不是逐字节:byte[] buffer = new byte[4096]; for (int c = zin.read(buffer); c != -1; c = zin.read(buffer)) fout.write(buffer, 0, c);
@nobre 你认为相同的代码可以用于解压或解压扩展 APK 扩展文件 obb 文件吗?
这里是 Xamarin.Android 版本:gist.github.com/pauldendulk/18958a610adb50990d96【参考方案2】:
要解压受密码保护的文件,请使用此库:
http://www.lingala.net/zip4j/download.php
就是这么简单。
ZipFile zipFile = new ZipFile(YourZipFile);
if(zipFile.isEncrypted())
zipFile.setPassword(Password);
zipFile.extractAll(Destination);
【讨论】:
【参考方案3】:这是使用 Apache 的 IOUtils.copy()
复制文件和 finally
块的 Samir 代码的更简洁版本。如果存档中有大文件,最好使用IOUtils.copyLarge()
。
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ZipUtils
public static void unzip(InputStream is, File path)
checkDir(path);
ZipInputStream zis = null;
FileOutputStream fos = null;
try
zis = new ZipInputStream(is);
ZipEntry ze;
while ((ze = zis.getNextEntry()) != null)
File entryFile = new File(path, ze.getName());
if (ze.isDirectory())
checkDir(entryFile);
else
fos = new FileOutputStream(entryFile);
IOUtils.copy(zis, fos);
fos.close();
fos = null;
zis.closeEntry();
catch (IOException e)
e.printStackTrace();
finally
if (zis != null)
try
zis.close();
catch (IOException ignore)
if (fos != null)
try
fos.close();
catch (IOException ignore)
private static void checkDir(File path)
if (!path.exists())
path.mkdirs();
else if (!path.isDirectory())
throw new IllegalArgumentException("Path is not directory");
【讨论】:
【参考方案4】:其他答案在 kitkat 及更高版本中的 sdcard(Environment.getExternalStorageDirectory() != SDCARD) 上并不适用。 但是您可以将此代码用于 api 21 及更高版本!获取更多帮助以获取 zipDocumentFile 阅读 this :
/**
* @return true->successful
*/
public static Boolean unzip(Context context, DocumentFile zipDocumentFile)
try
InputStream inputStream = context.getContentResolver().openInputStream(zipDocumentFile.getUri());
assert inputStream != null;
ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(inputStream, BUFFER_SIZE));
ZipEntry ze;
while ((ze = zipInputStream.getNextEntry()) != null)
if (ze.isDirectory())
String[] paths = ze.getName().split("/");
DocumentFile documentFile = null;
for (String path : paths)
if (documentFile == null)
documentFile = zipDocumentFile.getParentFile().findFile(path);
if (documentFile == null)
documentFile = zipDocumentFile.getParentFile().createDirectory(path);
else
DocumentFile newDocumentFile = documentFile.findFile(path);
if (newDocumentFile == null)
documentFile = documentFile.createDirectory(path);
else
documentFile = newDocumentFile;
if (documentFile == null || !documentFile.exists())
return false;
else
String[] paths = ze.getName().split("/");
//Make Folders
DocumentFile documentFile = null;
for (int i = 0; i < paths.length - 1; i++)
if (documentFile == null)
documentFile = zipDocumentFile.getParentFile().findFile(paths[i]);
if (documentFile == null)
documentFile = zipDocumentFile.getParentFile().createDirectory(paths[i]);
else
DocumentFile newDocumentFile = documentFile.findFile(paths[i]);
if (newDocumentFile == null)
documentFile = documentFile.createDirectory(paths[i]);
else
documentFile = newDocumentFile;
DocumentFile unzipDocumentFile;
if (documentFile == null)
unzipDocumentFile = zipDocumentFile.getParentFile().createFile(URLConnection.guessContentTypeFromName(ze.getName()), paths[paths.length - 1]);
else
unzipDocumentFile = documentFile.createFile(URLConnection.guessContentTypeFromName(ze.getName()), paths[paths.length - 1]);
// unzip the file
OutputStream outputStream = context.getContentResolver().openOutputStream(unzipDocumentFile.getUri());
int read;
byte[] data = new byte[BUFFER_SIZE];
assert outputStream != null;
while ((read = zipInputStream.read(data, 0, BUFFER_SIZE)) != -1)
outputStream.write(data, 0, read);
zipInputStream.closeEntry();
return true;
catch (Exception e)
e.printStackTrace();
return false;
【讨论】:
以上是关于在 Android 应用程序中解压缩 sd 卡上的压缩文件的主要内容,如果未能解决你的问题,请参考以下文章