如何解压缩大型zip文件&在更短的时间内写入SDCARD

时间:2013-01-08 15:18:48

标签: android iphone android-ndk zip unzip

要解压缩zip文件我通过引用this使用了包java.util.zip *中的类,并且它正常工作但是解压缩40MB的文件需要59秒。当我在iPhone项目上尝试相同的zip文件时(我们正在开发适用于两个平台的应用程序--Android& iPone& amp;具有解压缩zip文件的功能,并将解压缩的内容保存到SDCARD-Android或文档目录 - iPhone ),只需14秒。 iPhone应用使用ziparchive

所以我的问题是:

1.从上面的实验中可以看出解压缩& amp;与iPhone应用程序相比,Java中对SDCARD的文件写入操作消耗的时间更多,因此我决定使用C / C ++级解压缩&使用NDK进行文件写入操作。 这是正确的选择吗?

2.我搜索了谷歌,stackoverflow&一些人建议使用minizip但是没有足够的帮助来解决如何在android中使用minizip。 anyboday已经尝试过minizip for android吗?

3.我也尝试 NDK开发libz 来实现我的目标,因为Libz被添加到NDK但没有得到如何使用它。在NDK有人试过libz吗?

4.还有Java或C / C ++中的任何其他框架解压缩大型zip文件&在更短的时间内将它们写入SDCARD?

请帮帮我。

这是我的Java解压缩代码:

public String unzip() {

    String result;

    try {

        FileInputStream fin = new FileInputStream(this.filePath);
        ZipInputStream zin = new ZipInputStream(fin);
        ZipEntry ze = null;

        while ((ze = zin.getNextEntry()) != null) {

            Log.v("Unzip", "Unzipping " + ze.getName());

            if (ze.isDirectory()) {
                _dirChecker(ze.getName());
            } else {

                // Read 16 k at a time 
                byte[] buffer = new byte[16*1024];
                 int read;

                FileOutputStream fout = new FileOutputStream(this.location+ "/" + ze.getName());

                while ((read = zin.read(buffer)) != -1)
                {
                    fout.write(buffer, 0, read);
                }


                zin.closeEntry();
                fout.close();
            }

        }

        zin.close();
        result = "success";

    } catch (Exception e) {
        Log.e("unzip", "unzip", e);
        result = "failure";
    }

    return result;
}

4 个答案:

答案 0 :(得分:5)

你为什么不尝试这个代码。它很棒

    String zipname = "data.zip";
FileInputStream fis = new FileInputStream(zipname);
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
ZipEntry entry;

while ((entry = zis.getNextEntry()) != null) {
  System.out.println("Unzipping: " + entry.getName());

  int size;
  byte[] buffer = new byte[2048];

  FileOutputStream fos = new FileOutputStream(entry.getName());
  BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length);

  while ((size = zis.read(buffer, 0, buffer.length)) != -1) {
    bos.write(buffer, 0, size);
  }
  bos.flush();
  bos.close();
}
zis.close();
fis.close();

}

答案 1 :(得分:4)

所有解压缩代码最终都以zlib结尾。 Android核心库中没有“deflate”压缩的Java实现。

java.util.Zip应该比“本机”解压缩慢的唯一原因是文件I / O做得很糟糕,例如有些事情是使用非常小的缓冲区查看从问题链接的代码,这正是发生的事情 - 它在单个字节上运行。

该解决方案的一个评论提供了一个使用4K缓冲区的补丁。放下它,看看你的表现会发生什么。

答案 2 :(得分:1)

尝试将40Mb文件写入SDCard并测量花费的时间。 (几乎)所有免费(甚至付费)的zip存档支持库实现都基于相同的zlib代码,这在解压缩过程中占用了大部分处理速度。 Java代码应该比原生代码慢得多,所以我建议尝试NDK解压缩。此外,尝试以零压缩级别解压缩存档将使您猜测解压缩代码需要多长时间以及花费在数据复制上的时间。

答案 3 :(得分:0)

public boolean unzip(String zipfilepath, String destinationdir) {

            try {
                FileInputStream fis = new FileInputStream(zipfilepath);
                ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
                ZipEntry entry;

                while ((entry = zis.getNextEntry()) != null) {
                  System.out.println("Unzipping: " + entry.getName());

                  int size;
                  byte[] buffer = new byte[2048];

                  FileOutputStream fos = new FileOutputStream(destinationdir+ "/" + entry.getName());
                  BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length);

                  while ((size = zis.read(buffer, 0, buffer.length)) != -1) {
                    bos.write(buffer, 0, size);
                  }
                  bos.flush();
                  bos.close();
                }
                zis.close();
                fis.close();
                return true;
                }catch(Exception e){
                    return false;
                }
        }



String zipfilepath = context.getFilesDir().getPath()+"/"+myfile.zip;
String  destinationdir = context.getFilesDir().getPath();


unzip(zipfilepath, destinationdir);