You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Okio 3.12.0在KMP中实现Deflate压缩解压缩时的异常问题排查

Okio 3.12.0在KMP中实现Deflate压缩解压缩时的异常问题排查

我来帮你定位这个问题——你的Okio压缩函数里漏掉了关键的压缩收尾操作,导致压缩数据根本没被真正写入输出Buffer里,这就是为什么输出size为0,后续解压会抛出EOF异常的原因。

问题根源分析

Java的DeflaterOutputStream在use块结束时会自动调用close()方法,这个方法会触发三个核心操作:

  1. 通知Deflater完成所有剩余数据的压缩(调用def.finish())
  2. 将Deflater缓冲中所有压缩后的数据写入输出流
  3. 关闭流资源

但Okio的DeflaterSink不会自动做这些收尾工作。你的原代码只是把数据写入了Deflater的输入缓冲,但Deflater还在等待更多输入,没有触发最终的压缩和数据刷出,所以输出Buffer始终是空的。

修复后的Okio压缩函数

只需要用use块包裹DeflaterSink(或者手动关闭它),就能确保压缩流程完整执行:

fun encode(sb : ByteArray): ByteArray {
    val source = Buffer()
    source.write(sb)
    val out = Buffer()
    
    // 使用use块自动关闭DeflaterSink,触发压缩收尾逻辑
    out.deflate().use { deflatorSink ->
        deflatorSink.write(source, source.size)
    }

    println(" org size = ${sb.size}")
    println("encoded size = ${out.size}")
    return out.readByteArray()
}

如果需要和Java版本一样指定压缩级别(比如level 5),可以显式创建指定级别的Deflater:

fun encode(sb : ByteArray): ByteArray {
    val source = Buffer()
    source.write(sb)
    val out = Buffer()
    val compressionLevel = 5
    
    out.deflate(deflater = Deflater(compressionLevel)).use { deflatorSink ->
        deflatorSink.write(source, source.size)
    }

    println(" org size = ${sb.size}")
    println("encoded size = ${out.size}")
    return out.readByteArray()
}

手动关闭的等价写法

如果不想用use块,也可以手动在finally块中关闭DeflaterSink,效果是一样的:

fun encode(sb : ByteArray): ByteArray {
    val source = Buffer()
    source.write(sb)
    val out = Buffer()
    val deflatorSink = out.deflate()
    
    try {
        deflatorSink.write(source, source.size)
    } finally {
        // 关键:关闭触发压缩收尾和数据刷出
        deflatorSink.close()
    }

    println(" org size = ${sb.size}")
    println("encoded size = ${out.size}")
    return out.readByteArray()
}

为什么你的JVM版本能工作?

Java的DeflaterOutputStream在use块结束时的自动关闭逻辑,替你完成了所有收尾工作。而Okio作为更底层的IO库,把这些控制权交给了开发者,需要显式触发收尾操作。

修复后,你的KMP测试代码应该就能和JVM版本一样正常运行,压缩和解压后的大小也能匹配预期了。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 14:20:26