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

Posted

技术标签:

【中文标题】如何在 Java 中更快地解压 XZ 文件?【英文标题】:How to decompress an XZ file faster in Java? 【发布时间】:2014-03-15 09:10:25 【问题描述】:

大小为 85MB 的我的 SQLite db 文件使用 XZ 格式压缩,其大小已减少到 16MB。我使用下面的代码(以及XZ for Java提供的一个JAR)在android Jelly Bean中解压:

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。

不知道是不是我的代码做错了,或者有什么办法可以加快这个解压过程。

【问题讨论】:

这个怎么样:sqlite.org/fts3.html,见压缩选项 哦,我忘了我的 sqlite db 已经很紧凑了。 所以你的意思是它已经被压缩了?即使 xz 将其缩短到原始大小的 20%? 我的意思是我的 sqlite 数据库已经很紧凑了(比如使用紧凑型数据库,Firefox SQLite 管理器)。在此之后,XZ 进行了良好的压缩。 不。我的数据库是保存在 sdcard 上的外部数据库。我对 XZ 很满意,所以我想去。 【参考方案1】:

我认为你可以做些什么来加快速度。如果将 16Mb 解压到 85Mb 需要 2 分钟,那么很可能大部分时间都花在了实际的解压上,而其余大部分时间都花在了实际的文件 I/O 上……在物理层面上。

当然,您的代码并没有明显低效的地方。您正在使用 BufferedInputStream 读取并使用大缓冲区进行解码/写入。因此,您将有效地执行 I/O 系统调用。 (添加 BufferedOutputStream 不会有任何区别,因为您已经在从 8192 字节缓冲区进行大量写入。)


我能建议的最好方法是分析代码以查看热点的真正位置。但我怀疑你找不到任何可以改进到足以产生影响的东西。


我想选择 XZ,因为它在我的情况下具有最好的压缩级别,这在一定程度上节省了下载时间...(使用 zip,解压缩此文件只需大约 15 秒!

嗯,解压缩中额外的 CPU 时间是使用最高压缩算法所付出的代价。您需要决定哪个对您的用户更重要:更快的下载,或更快的数据库解压(安装?)。

FWIW,ZIP 解压缩可能是在本机库中实现的,而不是在纯 Java 中。它当然适用于 Oracle / OpenJDK JVM。

【讨论】:

【参考方案2】:

您至少应该将FileOutputStream 包装成BufferedOutputStream,在极少数情况下您不应该使用BufferedInputStream/BufferedOutputStream。试试看,看看现在需要多长时间。

【讨论】:

我的意思不是FileOutputStream out = new FileOutputStream(des + "myDecompressed");,而是BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(des + "myDecompressed")); 谢谢,但运气不好。解压那个文件还是需要两分钟多的时间! 尝试完全删除对文件的写入并对其计时(因此它只进行读取和解压缩),如果所花费的时间仍然非常接近您现在得到的时间,那么就是解压缩占用了所有时间。在这种情况下,我想您可以尝试找到另一种压缩方法,或者尝试使用本机 C 进行解压缩。 @NiamhDoyle 另外,你为什么要压缩它?那么您的应用可以满足 50MB APK 的限制吗?根据DB内容的敏感度,可以将db做成扩展下载(developer.android.com/google/play/expansion-files.html) 谢谢,凯。我的应用程序(及其数据库)不适合 50MB APK。事实上,我在 .OBB 中的一个文件中使用了 .OBB 扩展和这个 XZ 文件。我想选择 XZ,因为它在我的情况下具有最好的压缩级别,这在一定程度上节省了下载时间......(使用 zip,解压缩此文件只需大约 15 秒!)

以上是关于如何在 Java 中更快地解压 XZ 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 sharpcompress 解压 .xz (lzma2) 文件

在 C 代码中解压 .xz 文件

如何使用 7z SDK 压缩和解压 XZ 文件

tar.xz文件如何解压

Linux如何解压tar.xz文件

如何解压.tar.xz