7

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

所以我的问题是:

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

2.我在 google、stackoverflow 和一些建议使用minizip上进行了搜索,但对于如何在 android 中使用 minizip 没有足够的帮助。有人尝试过适用于 android 的 minizip 吗?

3.我还尝试了libz的NDK开发来实现我的目标,因为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

4 回答 4

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();

}

于 2013-03-14T12:58:14.487 回答
4

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

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

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

于 2013-01-09T01:00:43.723 回答
1

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

于 2013-01-08T15:42:47.070 回答
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);
于 2014-04-10T11:04:30.430 回答