如何在Android中使用XZ库实现文件压缩/解压?求经验或教程
Android平台使用XZ库实现文件压缩与解压
我之前在Android项目里折腾过这个XZ Java库,刚好能给你分享实操经验!下面一步步来,从集成到代码实现都给你理清楚:
1. 集成XZ库依赖
首先在你的app模块的build.gradle(如果用Kotlin DSL就是build.gradle.kts)中添加依赖,直接从Maven仓库获取稳定版本:
dependencies { implementation 'org.tukaani:xz:1.9' }
版本号可以根据官方更新调整,1.9是目前比较稳定的版本。
2. 文件压缩实现(XZ格式)
Java版本
import org.tukaani.xz.LZMA2Options; import org.tukaani.xz.XZOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class XZCompressor { public static void compressFile(File sourceFile, File targetFile) throws IOException { // 设置压缩级别(0-9),级别越高压缩率越高但速度越慢,推荐6级平衡性能 LZMA2Options options = new LZMA2Options(6); // 使用try-with-resources自动关闭流,避免资源泄漏 try (FileInputStream fis = new FileInputStream(sourceFile); FileOutputStream fos = new FileOutputStream(targetFile); XZOutputStream xzOs = new XZOutputStream(fos, options)) { byte[] buffer = new byte[8192]; // 8KB缓冲区,适配移动端内存 int bytesRead; while ((bytesRead = fis.read(buffer)) != -1) { xzOs.write(buffer, 0, bytesRead); } } } }
调用示例(记得在子线程执行,避免阻塞主线程):
new Thread(() -> { try { File source = new File(getFilesDir(), "original.txt"); File compressed = new File(getFilesDir(), "compressed.xz"); XZCompressor.compressFile(source, compressed); // 压缩完成后可以通过Handler或LiveData通知UI更新 } catch (IOException e) { e.printStackTrace(); // 处理异常,比如提示用户压缩失败 } }).start();
Kotlin版本
import org.tukaani.xz.LZMA2Options import org.tukaani.xz.XZOutputStream import java.io.File import java.io.FileInputStream import java.io.FileOutputStream object XZCompressor { @Throws(IOException::class) fun compressFile(sourceFile: File, targetFile: File) { val options = LZMA2Options(6) // Kotlin的use函数自动管理流资源 FileInputStream(sourceFile).use { fis -> FileOutputStream(targetFile).use { fos -> XZOutputStream(fos, options).use { xzOs -> val buffer = ByteArray(8192) var bytesRead: Int while (fis.read(buffer).also { bytesRead = it } != -1) { xzOs.write(buffer, 0, bytesRead) } } } } } }
调用示例(用Coroutine更符合Android Kotlin开发习惯):
lifecycleScope.launch(Dispatchers.IO) { try { val source = File(filesDir, "original.txt") val compressed = File(filesDir, "compressed.xz") XZCompressor.compressFile(source, compressed) withContext(Dispatchers.Main) { // 更新UI,比如显示压缩完成提示 } } catch (e: IOException) { e.printStackTrace() withContext(Dispatchers.Main) { // 提示用户压缩失败 } } }
3. 文件解压实现
Java版本
import org.tukaani.xz.XZInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class XZDecompressor { public static void decompressFile(File compressedFile, File targetFile) throws IOException { try (FileInputStream fis = new FileInputStream(compressedFile); XZInputStream xzIs = new XZInputStream(fis); FileOutputStream fos = new FileOutputStream(targetFile)) { byte[] buffer = new byte[8192]; int bytesRead; while ((bytesRead = xzIs.read(buffer)) != -1) { fos.write(buffer, 0, bytesRead); } } } }
调用示例:
new Thread(() -> { try { File compressed = new File(getFilesDir(), "compressed.xz"); File decompressed = new File(getFilesDir(), "decompressed.txt"); XZDecompressor.decompressFile(compressed, decompressed); // 通知UI解压完成 } catch (IOException e) { e.printStackTrace(); // 处理解压异常 } }).start();
Kotlin版本
import org.tukaani.xz.XZInputStream import java.io.File import java.io.FileInputStream import java.io.FileOutputStream object XZDecompressor { @Throws(IOException::class) fun decompressFile(compressedFile: File, targetFile: File) { FileInputStream(compressedFile).use { fis -> XZInputStream(fis).use { xzIs -> FileOutputStream(targetFile).use { fos -> val buffer = ByteArray(8192) var bytesRead: Int while (xzIs.read(buffer).also { bytesRead = it } != -1) { fos.write(buffer, 0, bytesRead) } } } } } }
调用示例:
lifecycleScope.launch(Dispatchers.IO) { try { val compressed = File(filesDir, "compressed.xz") val decompressed = File(filesDir, "decompressed.txt") XZDecompressor.decompressFile(compressed, decompressed) withContext(Dispatchers.Main) { // 更新UI提示解压完成 } } catch (e: IOException) { e.printStackTrace() withContext(Dispatchers.Main) { // 提示用户解压失败 } } }
4. 关键注意事项
- 权限处理:如果操作外部存储的文件,需要在
AndroidManifest.xml添加读写权限,Android 6.0+还要动态申请:
Android 10及以上建议使用Scoped Storage,规避传统存储权限的限制。<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - 线程安全:压缩/解压是耗时操作,必须放在子线程执行,否则会触发ANR(应用无响应)。推荐用Kotlin Coroutine或者Java的
ExecutorService。 - 压缩级别选择:LZMA2的0-9级,级别越高压缩率越高,但速度越慢、内存占用越大。移动端推荐4-6级,平衡性能和压缩效果。
- 异常处理:务必捕获
IOException,处理文件不存在、读写失败、磁盘空间不足等场景,给用户清晰的错误提示。
内容的提问来源于stack exchange,提问作者Saroj Raut
相关产品推荐
相关产品推荐

