如何加快 Java / Android 中的解压缩时间?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4504291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to speed up unzipping time in Java / Android?
提问by digitalWestie
Unzipping files on android seems to be dreadfully slow. At first I thought this was just the emulator but it appears to be the same on the phone. I've tried different compression levels, and eventually dropped down to storage mode but it still takes ages.
在 android 上解压缩文件似乎非常慢。起初我以为这只是模拟器,但在手机上似乎是一样的。我尝试了不同的压缩级别,最终降到存储模式,但仍然需要很长时间。
Anyway, there must be a reason! Does anyone else have this problem? My unzip method looks like this:
不管怎样,一定是有原因的!还有其他人有这个问题吗?我的解压缩方法如下所示:
public void unzip()
{
try{
FileInputStream fin = new FileInputStream(zipFile);
ZipInputStream zin = new ZipInputStream(fin);
File rootfolder = new File(directory);
rootfolder.mkdirs();
ZipEntry ze = null;
while ((ze = zin.getNextEntry())!=null){
if(ze.isDirectory()){
dirChecker(ze.getName());
}
else{
FileOutputStream fout = new FileOutputStream(directory+ze.getName());
for(int c = zin.read();c!=-1;c=zin.read()){
fout.write(c);
}
//Debug.out("Closing streams");
zin.closeEntry();
fout.close();
}
}
zin.close();
}
catch(Exception e){
//Debug.out("Error trying to unzip file " + zipFile);
}
}
回答by Robert Kolner
I don't know if unzipping on Android is slow, but copying byte for byte in a loop is surely slowing it down even more. Try using BufferedInputStream and BufferedOutputStream - it might be a bit more complicated, but in my experience it is worth it in the end.
我不知道在 Android 上解压缩是否很慢,但是在循环中逐字节复制肯定会减慢它的速度。尝试使用 BufferedInputStream 和 BufferedOutputStream - 它可能有点复杂,但根据我的经验,它最终是值得的。
BufferedInputStream in = new BufferedInputStream(zin);
BufferedOutputStream out = new BufferedOutputStream(fout);
And then you can write with something like that:
然后你可以写这样的东西:
byte b[] = new byte[1024];
int n;
while ((n = in.read(b,0,1024)) >= 0) {
out.write(b,0,n);
}
回答by thoxxer
Thanks for the solution Robert. I modified my unzip method and now it takes only a few seconds instead of 2 minutes. Maybe someone's interested in my solution. So here you go:
感谢罗伯特的解决方案。我修改了解压缩方法,现在只需几秒钟而不是 2 分钟。也许有人对我的解决方案感兴趣。所以给你:
public void unzip() {
try {
FileInputStream inputStream = new FileInputStream(filePath);
ZipInputStream zipStream = new ZipInputStream(inputStream);
ZipEntry zEntry = null;
while ((zEntry = zipStream.getNextEntry()) != null) {
Log.d("Unzip", "Unzipping " + zEntry.getName() + " at "
+ destination);
if (zEntry.isDirectory()) {
hanldeDirectory(zEntry.getName());
} else {
FileOutputStream fout = new FileOutputStream(
this.destination + "/" + zEntry.getName());
BufferedOutputStream bufout = new BufferedOutputStream(fout);
byte[] buffer = new byte[1024];
int read = 0;
while ((read = zipStream.read(buffer)) != -1) {
bufout.write(buffer, 0, read);
}
zipStream.closeEntry();
bufout.close();
fout.close();
}
}
zipStream.close();
Log.d("Unzip", "Unzipping complete. path : " + destination);
} catch (Exception e) {
Log.d("Unzip", "Unzipping failed");
e.printStackTrace();
}
}
public void hanldeDirectory(String dir) {
File f = new File(this.destination + dir);
if (!f.isDirectory()) {
f.mkdirs();
}
}
回答by Manohar Reddy
Using above ideas and ideas from some other sources I have created this class
使用上述想法和其他一些来源的想法我创建了这个类
Create this new class
创建这个新类
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();
}
}
}
USAGE
用法
just pass your file location of zip file and your destination Location to this class
example
只需将您的 zip 文件的文件位置和您的目标位置传递给此类
示例
String zipFile = Environment.getExternalStorageDirectory() + "/the_raven.zip"; //your zip file location
String unzipLocation = Environment.getExternalStorageDirectory() + "/unzippedtestNew/"; // unzip location
DecompressFast df= new DecompressFast(zipFile, unzipLocation);
df.unzip();
Dont Forget to add following permissions in manifest(also Run time permission if version higher than marshmellow)
不要忘记在清单中添加以下权限(如果版本高于 marshmellow,还有运行时权限)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
hope this helps
希望这可以帮助
回答by hafridi
The URL that helped me learn how to zip and unzip can be found here.
可以在此处找到帮助我学习如何压缩和解压缩的 URL 。
I used that URL in conjuction with user3203118's answer above for unzipping. This is for future references for people who run in to this issue and need help solving it.
我将该 URL 与上面 user3203118 的回答结合使用以进行解压缩。这是将来遇到此问题并需要帮助解决它的人的参考。
Below is the ZipManager code I am using:
下面是我正在使用的 ZipManager 代码:
public class ZipManager {
private static final int BUFFER = 80000;
public void zip(String[] _files, String zipFileName) {
try {
BufferedInputStream origin = null;
FileOutputStream dest = new FileOutputStream(zipFileName);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
dest));
byte data[] = new byte[BUFFER];
for (int i = 0; i < _files.length; i++) {
Log.v("Compress", "Adding: " + _files[i]);
FileInputStream fi = new FileInputStream(_files[i]);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(_files[i].substring(_files[i]
.lastIndexOf("/") + 1));
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void unzip(String _zipFile, String _targetLocation) {
// create target location folder if not exist
dirChecker(_targetLocation);
try {
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
// create dir if required while unzipping
if (ze.isDirectory()) {
dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(
_targetLocation + "/" + 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);
}
zin.closeEntry();
bufout.close();
fout.close();
}
}
zin.close();
} catch (Exception e) {
System.out.println(e);
}
}
private void dirChecker(String dir) {
File f = new File(dir);
if (!f.isDirectory()) {
f.mkdirs();
}
}
}
回答by Deepak Sharma
Just call this method and it will give you much better performance..
只需调用此方法,它将为您提供更好的性能..
public boolean unzip(Context context) {
try {
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
BufferedInputStream in = new BufferedInputStream(zin);
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 out = new BufferedOutputStream(fout);
byte b[] = new byte[1024];
for (int c = in.read(b,0,1024); c != -1; c = in.read()) {
out.write(b,0,c);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
return true;
} catch (Exception e) {
Log.e("Decompress", "unzip", e);
return false;
}
}
private void _dirChecker(String dir) {
File f = new File(_location + dir);
if (!f.isDirectory()) {
f.mkdirs();
}
}
回答by crack_head
In case of using BufferedOutputStream be sure to flush it. If you do not do it, size smaller than buffer will not be unzipped properly
在使用 BufferedOutputStream 的情况下,一定要刷新它。如果不这样做,小于缓冲区的大小将无法正确解压缩
if (ze.isDirectory()) {
_dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(_location
+ ze.getName());
BufferedOutputStream out = new BufferedOutputStream(fout);
byte buffer[] = new byte[1024];
for (int c = in.read(buffer,0,1024); c != -1; c = in.read()) {
out.write(buffer,0,c);
}
out.flush();//flush it......
zin.closeEntry();
fout.close();
}