HarmonyOS 鸿蒙Next中使用zlib压缩buffer,如何动态设置目标缓冲区的数据长度

发布于 1周前 作者 caililin 来自 鸿蒙OS

HarmonyOS 鸿蒙Next中使用zlib压缩buffer,如何动态设置目标缓冲区的数据长度

使用zlib解压buffer,如何动态设置目标缓冲区的数据长度-数据与文件-开发-常见问题手册 - 华为HarmonyOS开发者

其实就是在上面的链接代码基础上,将inflate修改为deflate接口即可。

static async compress(str: string): Promise<ArrayBuffer> {
    let zip = zlib.createZipSync()
    let inBuf = StringUtil.stringToUint8Array(str).buffer as ArrayBuffer
    let strm: zlib.ZStream = {};
    let BUFLEN = 4096;
    let count = inBuf.byteLength / BUFLEN
    if (count > 1) {
      BUFLEN *= count
    }

    let outBuf = new ArrayBuffer(BUFLEN);
    let output: ArrayBuffer[] = []; // 用于存储压缩后的数据

    let initStatus = zip.deflateInit(strm, zlib.CompressLevel.COMPRESS_LEVEL_BEST_SPEED);
    console.debug('deflateInit ret: ' + (await initStatus).valueOf());

    let offset = 0; // 用于跟踪读取的字节数
    do {
      let readLen = Math.min(BUFLEN, inBuf.byteLength - offset);
      if (readLen <= 0) {
        break;
      }

      strm.availableIn = readLen;
      strm.nextIn = inBuf.slice(offset, offset + readLen);
      offset += readLen; // 更新偏移量

      do {
        strm.availableOut = BUFLEN;
        strm.nextOut = outBuf; // 压缩后的输出字节

        try {
          let inflateStatus = zip.deflate(strm, zlib.CompressFlushMode.FINISH);
          console.debug('deflate ret: ' + (await inflateStatus).valueOf());

          let innerStrm = zip.getZStream();
          strm.availableIn = (await innerStrm).availableIn;
          strm.nextIn = (await innerStrm).nextIn;
          strm.availableOut = (await innerStrm).availableOut;
          strm.nextOut = (await innerStrm).nextOut;
          strm.totalIn = (await innerStrm).totalIn;
          strm.totalOut = (await innerStrm).totalOut;

          if (strm.availableOut != undefined) {
            let have = BUFLEN - strm.availableOut;
            if (have > 0) {
              // 将解压后的数据存储到 output 数组中
              output.push(outBuf.slice(0, have));
            }
          }
        } catch (err) {
          //LoggerUtil.error('inflate err: ' + JSON.stringify(err))
          //console.debug('inflate err: ' + JSON.stringify(err));
        }
      } while (strm.availableOut == 0);
    } while (strm.availableIn! > 0 || strm.availableOut! > 0);

    zip.deflateEnd(strm);

    // 将 output 数组中的 Uint8Array 合并为一个单一的 Uint8Array
    let totalLength = output.reduce((acc, val) => acc + val.byteLength, 0);
    // 解压后的buff
    let result = new Uint8Array(totalLength);
    let pos = 0;
    for (let arr of output) {
      // 将 ArrayBuffer 转换为 Uint8Array
      let u = new Uint8Array(arr);
      // 将解压后的数据写入 result
      result.set(u, pos);
      // 更新位置
      pos += u.byteLength;
    }
    return result.buffer
}

更多关于HarmonyOS 鸿蒙Next中使用zlib压缩buffer,如何动态设置目标缓冲区的数据长度的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

在HarmonyOS鸿蒙Next中,使用zlib压缩buffer时,动态设置目标缓冲区的数据长度可以通过compressBound函数来实现。compressBound函数用于估算压缩后的数据最大长度,确保目标缓冲区足够大。具体步骤如下:

  1. 引入zlib库:#include <zlib.h>
  2. 使用compressBound函数计算压缩后的最大长度:uLong destLen = compressBound(sourceLen);,其中sourceLen是源数据的长度。
  3. 根据destLen动态分配目标缓冲区:Bytef *dest = (Bytef *)malloc(destLen);
  4. 调用compress函数进行压缩:compress(dest, &destLen, source, sourceLen);,其中source是源数据缓冲区,sourceLen是源数据长度,dest是目标缓冲区,destLen是目标缓冲区长度。
  5. 压缩完成后,destLen将更新为实际压缩后的数据长度。

通过这种方式,可以动态设置目标缓冲区的数据长度,确保压缩操作顺利进行。

更多关于HarmonyOS 鸿蒙Next中使用zlib压缩buffer,如何动态设置目标缓冲区的数据长度的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中使用zlib压缩buffer时,可以通过compressBound函数动态设置目标缓冲区的数据长度。compressBound函数会根据源数据的长度,返回压缩后的最大可能长度。你可以在压缩前调用此函数,确保目标缓冲区有足够的空间。示例代码如下:

uLong sourceLen = /* 源数据长度 */;
uLong destLen = compressBound(sourceLen); // 动态计算目标缓冲区长度
Bytef* destBuffer = (Bytef*)malloc(destLen); // 分配目标缓冲区

// 进行压缩操作
compress(destBuffer, &destLen, sourceBuffer, sourceLen);

// 使用压缩后的数据
// ...

free(destBuffer); // 释放目标缓冲区

这样可以避免缓冲区溢出,并确保压缩操作顺利进行。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!