Zstd 壓縮算法
簡介
最近維護(hù)一個(gè)老的緩存系統(tǒng),使用RUST語音實(shí)現(xiàn),底層使用磁盤緩存。因?yàn)槿藛T離職,打算用JAVA
/KOTLIN
重新實(shí)現(xiàn)一遍。
考慮到歷史緩存數(shù)量比較大,采用灰度模式,復(fù)用歷史緩存,只是程序改成JAVA版本。剛剛開始一切比較順利,但是上線以后顯示歷史緩存錯(cuò)誤,比如hash不一樣。
仔細(xì)翻看歷史代碼,底部存儲(chǔ)使用了一種叫做zstd
的一種壓縮算法,找找資料,發(fā)現(xiàn)這個(gè)還挺牛的,特記錄下。
Zstd,全稱 Zstandard,是 Facebook 于 2016 年開源的新無損壓縮算法。與 zlib、lz4、xz 等當(dāng)前流行的壓縮算法不同,Zstd 尋求一種壓縮性能與壓縮率通吃的方案,而實(shí)際上它也確實(shí)做到了。在由官方所列出的表格中,可以看到,Zstd 不僅具備優(yōu)秀的壓縮性能,在壓縮率上也有非常亮眼的表現(xiàn)。官方資料。
Zstd-jni
Zstd-jni,顧名思義,是基于 Zstd 本地庫實(shí)現(xiàn)的 Java 調(diào)用接口。它支持通過 Java 語言實(shí)現(xiàn) Zstd 的壓縮與解壓縮。
在 Zstd-jni 的三方包中,主要實(shí)現(xiàn)了以下功能:
- 提供靜態(tài)的壓縮與解壓縮方法
- 支持壓縮數(shù)據(jù)的流式傳輸
- 支持字典文件的訓(xùn)練與添加
代碼示例
添加依賴
// https://github.com/luben/zstd-jni
implementation("com.github.luben:zstd-jni:1.4.9-5")
讀取歷史文件,解壓數(shù)據(jù),寫入到新文件。
private fun convertOldToNew(file: File, path: String): File {
val src = file.inputStream().use { it.readBytes() }
// 真坑,還要給大小
val size = when {
src.size < 10_000 -> src.size * 2
src.size < 100_000 -> src.size * 3
else -> src.size * 4
}
val dst = ByteArray(size)
val len = Zstd.decompress(dst, src)
val newFile = File(config.cacheDirFile(), path).apply { parentFile.mkdirs() }
newFile.outputStream().use { it.write(dst, 0, len.toInt()) }
log.error("convert old $file >>> $newFile, $len / ${file.length()}")
return newFile
}
Zstd Java Sdk 的版本就比較坑了,解壓的時(shí)候,還需要給出大小。