如何在android中使用XZ lib压缩/解压缩文件

时间:2018-01-17 12:39:01

标签: java android xz

https://tukaani.org/xz/java.html这个网站提供了一个用于压缩/解压缩文件的XZ库,我想试一试,但我迷路了。

有人有这方面的经验吗?还是教程?感谢。

3 个答案:

答案 0 :(得分:2)

我最近使用过这个库,这是我的github链接XZ compression algorithm上的工作代码。你可以在你的android项目中使用这个类。这是 Main 类,用于说明如何使用此类。

public static void main(String[] args){
  String input = "Some string blah blah blah";
  System.out.println("XZ or LZMA2 library.....");

  // If you are using some file instead of plain text you have to 
  //convert it to bytes here and pass it to `compress` method.

  byte[] xzCompressed = XZ_LZMA2.compress(input);
  System.out.println("Input length:" + input.length());
  System.out.println("XZ Compressed Length: "+ xzCompressed.length);
  String xzDecompressed = XZ_LZMA2.decompress(xzCompressed);
  System.out.println("XZ Decompressed : "+ xzDecompressed);

  // If you are using decompression for some compressed file instead of
  // plain text return bytes from `decompress` method and put it in 
  //FileOutputStream to get file back
}

注意: XZ压缩算法需要大量内存才能运行。 不建议将其用于Android 等任何移动平台。它会给你内存不足例外。 Android提供名为Deflater and Inflater ZLIB压缩库。这在Android平台上运行良好。

答案 1 :(得分:0)

您可以使用Android AOSP中的XZ-Java静态库或'org.tukaani:xz:1.8'lib压缩XZ文件格式的文件。这是将文件压缩为XZ格式的工作代码。创建用于压缩多个文件的Asynctask,并使用以下Java代码进行压缩。

Android.mk Changes for building in AOSP:
LOCAL_STATIC_JAVA_LIBRARIES := \
       xz-java
OR 

Gradle File Changes for building in Android Studio:
implementation 'org.tukaani:xz:1.8'

Java Code: 
public void CompressFile(String inputFile, String outputFile){
    XZOutputStream xzOStream = null;
        try {
            LZMA2Options opts = new LZMA2Options();
            opts.setPreset(7);

            FileOutputStream foStream = new FileOutputStream(outputFile);
            xzOStream = new XZOutputStream(foStream, opts);
            FileInputStream fiStream = new FileInputStream(inputFile);
            Scanner sc = null;

            try {
                sc = new Scanner(fiStream);
                while (sc.hasNextLine()) {
                    String line = sc.nextLine() + "\n";
                    xzOStream.write(line.getBytes(), 0, line.getBytes().length);
                }
                Utils.removeFile(inputFile);
            } finally {
                if (fiStream != null) {
                    fiStream.close();
                }

                if (sc != null) {
                    sc.close();
                }

                if(xzOStream != null)
                    xzOStream.close();

                if(foStream != null)
                    foStream.close();
            }
        }catch (Exception e){
            Log.e(TAG, "CompressFileXZ() Exception: " + e.toString());
        }
}

答案 2 :(得分:0)

我的Android应用在启动时会从其assets目录中加载数据文件,而且我已经知道解压缩后的大小,所以我只需要编写以下内容:

byte[] data = new byte[ /* decompressed size here */ ];
new org.tukaani.xz.XZInputStream(context.getAssets().open("file.xz")).read(data);

,然后git clone https://git.tukaani.org/xz-java.gitcp -r xz-java/src/org进入应用程序的src目录(并确保在我的.java命令行中提及所有javac文件-我仍在使用老式的命令行脚本来编译我的应用;我还没有为Android Studio或Gradle设置它们。

但是,生成的应用花了 6秒来解压缩2013 Sony Xperia Z Ultra(Android 4.4)上的3M压缩数据,并更改了{ {1}}并没有明显影响那6秒的启动。是的,它在运行Android 10的2018年三星S9上仅花费了1秒,但这是较旧的手机需要更多的压缩,因为它们是可用空间较小的手机,因此增加了无法接受的启动延迟较旧设备上的应用似乎是自欺欺人,尤其是当替代方案xz接近即时时:

java.util.zip.Inflater

对于这种快速启动,您只需支付APK大小比使用byte[] data = new byte[ /* compressed size here */]; context.getAssets().open("file.z").read(data); java.util.zip.Inflater i=new java.util.zip.Inflater(); i.setInput(data); byte[] decompressed=new byte[ /* decompressed size here */ ]; i.inflate(decompressed); i.end(); data = decompressed; /* allow earlier byte[] to be gc'd */ 文件的APK大小的20%的增加(我使用xz进行压缩以使其比{{1} },但仍比zopfli大。

Tukaani的代码当前似乎无法与gzip -9等效。 Tukaani的xz -0包含以下注释:“由于XZInputStream仍然在内部进行了一些缓冲,因此这里似乎不需要BufferedInputStream来提高性能”,但是出于完整性考虑,我还是尝试了:

setInput

但这对6秒的延迟没有明显的影响(因此,似乎注释是正确的:无论哪种方式,性能都一样差。)