如何在Java中更快地解压XZ文件?

5

我使用XZ格式压缩了一个大小为85MB的SQLite数据库文件,并将其压缩到16MB。 在Android Jelly Bean中,我使用以下代码(以及由XZ for Java提供的JAR)进行解压:

try { 
    FileInputStream fin = new FileInputStream(path + "myFile.xz");
    BufferedInputStream in = new BufferedInputStream(fin);
    FileOutputStream out = new FileOutputStream(des + "myDecompressed");
    XZInputStream xzIn = new XZInputStream(in);
    final byte[] buffer = new byte[8192];
    int n = 0;
    while (-1 != (n = xzIn.read(buffer))) {
        out.write(buffer, 0, n);
    } 
    out.close();
    xzIn.close();
}
catch(Exception e) { 
    Log.e("Decompress", "unzip", e); 
}

解压成功,但是需要超过两分钟才能完成。我认为这太长了,因为压缩文件仅有16MB而已,解压后的文件仅有85MB。

我想知道我是否在代码中做错了什么或者是否有方法可以加快解压速度。


这个怎么样:https://www.sqlite.org/fts3.html,看看压缩选项。 - pskink
哦,我忘记注明我的sqlite数据库已经压缩了。 - Niamh Doyle
那么你的意思是它已经被压缩了?即使使用xz将其缩短到原始大小的20%? - pskink
我的意思是我的sqlite数据库已经被压缩了(比如使用Compact Database,Firefox SQLite Manager)。在此之后,XZ进行了很好的压缩。 - Niamh Doyle
我相信这里的线程会有所帮助。 - user2889419
显示剩余3条评论
2个回答

2
我认为你很难让这个过程变得更快。如果将16Mb的文件解压缩到85Mb需要2分钟,那么大部分时间都用在了实际的解压缩上,剩下的很大一部分则是在实际的文件I/O操作中...即在物理层面上。
当然,你的代码没有明显的低效之处。你正在使用BufferedInputStream进行读取,并使用一个大缓冲区进行解码/写入操作。所以你会高效地执行I/O系统调用。(添加BufferedOutputStream不会有任何改变,因为你已经从8192字节的缓冲区进行了大量写入操作。)
最好的建议是对你的代码进行性能剖析,看看热点究竟在哪里。但是我怀疑你不会发现任何可以改进的地方,以便产生可见的影响。
引用:
“我想选择XZ,因为在我的情况下它具有最好的压缩水平,这在某种程度上可以节省下载时间...(用zip解压缩这个文件只需要大约15秒!)”
嗯,在解压缩时额外的CPU时间就是你使用已经达到最大压缩算法的代价。你需要决定对你的用户来说哪个更重要:更快的下载速度还是更快的数据库解压(安装)速度。
值得一提的是,ZIP解压缩可能是在本地库中实现的,而不是纯Java实现。至少对于Oracle / OpenJDK JVM来说是这样的。

1
你至少应该将 FileOutputStream 包装成一个 BufferedOutputStream,很少有情况下你不应该使用 BufferedInputStream/BufferedOutputStream。尝试一下,看看现在需要多长时间。

尝试完全删除文件写入并计时(仅进行读取和解压缩),如果所花费的时间仍非常接近当前时间,则说明解压缩占用了所有时间。在这种情况下,您可以尝试找到另一种压缩方法,或者尝试使用本地C进行解压缩。 - Kai
1
@NiamhDoyle 另外,你为什么想要压缩它?是为了让你的应用程序适应50MB APK限制吗?根据数据库内容的敏感性,你可以将数据库作为扩展下载 (http://developer.android.com/google/play/expansion-files.html)。 - Kai
谢谢,凯。我的应用程序(以及其数据库)不适合50MB的APK。事实上,我正在使用.OBB扩展和这个XZ文件在.OBB内的一个文件中。我想选择XZ,因为在我的情况下它具有最佳的压缩级别,这在某种程度上节省了下载时间...(使用zip,解压此文件仅需要约15秒!) - Niamh Doyle
关于你的帮助和@Stephen C提到的内容,我可能不得不忍受这种痛苦!!!已经尝试过zip、gzip(2)、lzma(2)、xz... - Niamh Doyle
@NiamhDoyle 我想,如果代码花费了相当长的时间来读/写数据,你可以通过并行运行读/写和解压缩来减少时间。现在,首先CPU什么也不做,只是等待数据,然后文件系统等待解压缩的数据,等等。但就我个人而言,如果zip压缩确实更快,我会选择zip并完成它。 - Kai
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接