HarmonyOS鸿蒙Next压缩和解压处理

HarmonyOS鸿蒙Next压缩和解压处理 一、方案思路

鸿蒙提供@ohos.zlib (Zip模块)进行压缩和解压的处理。需要注意的是,操作路径需要在沙箱中,那如果压缩包在项目工程资源文件夹中,需要提前对压缩包文件进行拷贝到沙箱路径的操作。

使用zlib.compressFile 进行压缩;zlib.decompressFile 进行解压缩。

另外,zlib接口暂不支持操作字节数组,这时可以使用三方库pako。

pako

二、zip示例

import { zlib, BusinessError } from '@kit.BasicServicesKit';
import { fileIo as fs } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import { util } from '@kit.ArkTS';

@Entry
@Component
struct ZipPage {

  private TAG: string = "ZipTestPage";
  @State mZipTestContent: string = "";

  // 指定的待解压缩文件的文件路径,文件后缀需要以.zip结尾。文件路径必须为沙箱路径,沙箱路径可以通过context获取
  private inFile = '/xx/xxx.zip';
  // 指定的解压后的文件夹路径,文件夹目录路径需要在系统中存在,不存在则会解压失败。
  // 沙箱路径通过context获取
  // 如果待解压的文件或文件夹在解压后的路径下已经存在,则会直接覆盖同名文件或同名文件夹中的同名文件。多个线程同时解压文件时,outFile不能相同。
  private outFileDir = '/xxx';
  // 解压的配置参数。
  private options: zlib.Options = {
    // 默认压缩等级。
    level: zlib.CompressLevel.COMPRESS_LEVEL_DEFAULT_COMPRESSION
  };

  aboutToAppear(): void {
    // 准备zip到沙箱路径下
    this.copyRawFileToLocal();
    // 填充待解压文件路径和解压后的文件路径
    this.setting();
  }

  private copyRawFileToLocal() {
    let context = getContext(this) as common.UIAbilityContext; 
    try {
      //获取resources/rawfile目录下对应的rawfile文件内容
      let val: Uint8Array = context.resourceManager.getRawFileContentSync("test.zip");
      console.info(this.TAG, "getRawFileContentSync done");
      let pathDir: string = context.filesDir;
      console.info(this.TAG, "pathDir: " + pathDir);
      // 待拷贝文件沙箱路径
      let filePath: string = pathDir + '/test.zip';
      console.info(this.TAG, "filePath: " + filePath);
      // 若文件不存在,则创建文件。
      let fileTarget = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
      console.info(this.TAG, "file done");
      let writeLen = fs.writeSync(fileTarget.fd, val.buffer as ArrayBuffer);
      console.info(this.TAG, "write data to file succeed and size is:" + writeLen);
      fs.closeSync(fileTarget);
    } catch (error) {
      let code = (error as BusinessError).code;
      let message = (error as BusinessError).message;
      console.error(this.TAG,`getRawFileContentSync failed, error code: ${code}, message: ${message}.`);
    }
  }
  
  private setting(){
    let pathDir: string = getContext().filesDir;
    console.info(this.TAG, "setting pathDir: " + pathDir);

    this.inFile = pathDir + '/test.zip';
    console.info(this.TAG, "setting inFile: " + this.inFile);

    this.outFileDir =  pathDir;
    console.info(this.TAG, "setting outFileDir: " + this.outFileDir);
  }

  // 解压
  onUnZip(){
    try {
      console.info(this.TAG, "onUnZip start");
      // 解压文件,解压的结果回调
      zlib.decompressFile(this.inFile, this.outFileDir, this.options, (errData: BusinessError) => {
        if (errData !== null) {
          console.error(this.TAG, `errData is errCode:${errData.code}  message:${errData.message}`);
        }
        console.info(this.TAG, "onUnZip done");
        // 解压成功后,去输出的路径下outFileDir,读取文件
        let fileTarget = fs.openSync(this.outFileDir + "/test.txt",  fs.OpenMode.READ_ONLY);
        let size = fs.statSync(fileTarget.fd).size;
        console.info(this.TAG, "onUnZip size: " + size);
        let bufferRes = new ArrayBuffer(size);
        let readLen = fs.readSync(fileTarget.fd, bufferRes);
        fs.closeSync(fileTarget);
        console.info(this.TAG, "onUnZip readLen: " + readLen);

        let decoder = util.TextDecoder.create('utf-8');
        let temp = new Uint8Array(bufferRes);
        let result = decoder.decodeToString(temp);
        console.info(this.TAG, "onUnZip text: " + result);
        this.mZipTestContent = result;

       
      })
    } catch (errData) {
      let code = (errData as BusinessError).code;
      let message = (errData as BusinessError).message;
      console.error(this.TAG, `errData is errCode:${code}  message:${message}`);
    }
  }

  build() {
    RelativeContainer() {
      Text("点击解压,内容: " + this.mZipTestContent)
        .id('ZipTestPageHelloWorld')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .onClick(this.onUnZip)
    }
    .height('100%')
    .width('100%')
  }
}

三、pako示例(GZIP)

gzip(str: string) {
    const data: Uint8Array | undefined = pako.gzip(str);
    let base64 = new util.Base64Helper;
    let str_zip = base64.encodeToStringSync(data);
    console.info(TAG, 'pako压缩' + str_zip);
    return str_zip;
  }
function unGzip(str: string){
  let decompressed: string = ''

  try {
    let base64 = new util.Base64Helper
    let data = base64.decodeSync(str)
   
    decompressed = pako.ungzip(data, {to :'string'});
    

  } catch (err) {
    console.log(TAG, 'pako解压失败' + JSON.stringify(err))
  }
  return decompressed;
}

更多关于HarmonyOS鸿蒙Next压缩和解压处理的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next压缩和解压处理的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


HarmonyOS Next提供了Zip类用于处理压缩和解压操作。压缩文件时,可以使用Zip.addEntry()方法添加文件或目录,然后调用Zip.finish()完成压缩。解压文件时,使用Zip.extractAll()方法将压缩包内容解压到指定目录。

示例代码:

import zlib from '@ohos.zlib';

// 压缩
let zip = new zlib.Zip();
zip.addEntry('file1.txt');
zip.addEntry('dir/');
zip.finish('output.zip');

// 解压
let zip = new zlib.Zip();
zip.extractAll('output.zip', 'extracted/');

Zip类支持ZIP格式,提供了基本的压缩和解压功能。更多详细操作可参考官方文档。

回到顶部