鸿蒙压缩解压开发指南【2】

2025-06-28 23:56:28
108次阅读
0个评论

第二篇:核心API实战篇

概述

在掌握了压缩解压技术的基本原理后,本篇将深入探讨鸿蒙系统 @ohos.zlib 模块的核心API使用方法。通过详细的代码示例和实践案例,帮助开发者快速掌握数据压缩、文件压缩、流式压缩等关键技术,并学会在实际项目中灵活运用这些技术来优化应用性能。

1. 数据压缩核心API

1.1 基础数据压缩

数据压缩是最基础也是最重要的功能,适用于处理内存中的数据对象。以下是实现基础数据压缩的完整示例:

/**
 * 压缩ArrayBuffer数据
 * @param sourceData 待压缩的原始数据
 * @param compressionLevel 压缩级别
 * @returns Promise<ArrayBuffer> 压缩后的数据
 */
async function compressData(sourceData: ArrayBuffer, compressionLevel: zlib.CompressLevel = zlib.CompressLevel.COMPRESS_LEVEL_DEFAULT_COMPRESSION): Promise<ArrayBuffer> {
  try {
    // 配置压缩参数
    const options: zlib.Options = {
      level: compressionLevel,                                    // 压缩级别
      memLevel: zlib.MemLevel.MEM_LEVEL_DEFAULT,                 // 内存使用级别
      strategy: zlib.CompressStrategy.COMPRESS_STRATEGY_DEFAULT_STRATEGY  // 压缩策略
    };
    
    // 执行压缩操作
    const compressedData = await zlib.compressFile(sourceData, options);
    
    // 计算压缩率
    const originalSize = sourceData.byteLength;
    const compressedSize = compressedData.byteLength;
    const compressionRatio = ((originalSize - compressedSize) / originalSize * 100).toFixed(2);
    
    console.log(`压缩完成:原始大小 ${originalSize} 字节,压缩后 ${compressedSize} 字节,压缩率 ${compressionRatio}%`);
    
    return compressedData;
  } catch (error) {
    const err = error as BusinessError;
    console.error(`数据压缩失败,错误代码: ${err.code},错误信息: ${err.message}`);
    throw error;
  }
}

这个函数展示了如何对内存中的ArrayBuffer数据进行压缩。压缩级别参数允许开发者在压缩率和压缩速度之间进行权衡。默认压缩级别通常能够在大多数场景下提供良好的性能表现。

1.2 数据解压缩实现

与压缩操作相对应,解压缩操作用于恢复原始数据:

/**
 * 解压缩ArrayBuffer数据
 * @param compressedData 压缩后的数据
 * @returns Promise<ArrayBuffer> 解压后的原始数据
 */
async function decompressData(compressedData: ArrayBuffer): Promise<ArrayBuffer> {
  try {
    // 配置解压参数
    const options: zlib.Options = {
      level: zlib.CompressLevel.COMPRESS_LEVEL_DEFAULT_COMPRESSION,
      memLevel: zlib.MemLevel.MEM_LEVEL_DEFAULT,
      strategy: zlib.CompressStrategy.COMPRESS_STRATEGY_DEFAULT_STRATEGY
    };
    
    // 执行解压操作
    const decompressedData = await zlib.decompressFile(compressedData, options);
    
    console.log(`解压完成:恢复数据大小 ${decompressedData.byteLength} 字节`);
    
    return decompressedData;
  } catch (error) {
    const err = error as BusinessError;
    console.error(`数据解压失败,错误代码: ${err.code},错误信息: ${err.message}`);
    throw error;
  }
}

1.3 字符串数据处理

在实际应用中,经常需要压缩文本数据。以下示例展示了如何处理字符串数据的压缩和解压:

/**
 * 压缩字符串数据
 * @param text 待压缩的文本字符串
 * @returns Promise<ArrayBuffer> 压缩后的数据
 */
async function compressString(text: string): Promise<ArrayBuffer> {
  try {
    // 将字符串转换为ArrayBuffer
    const encoder = new TextEncoder();
    const sourceData = encoder.encode(text).buffer;
    
    console.log(`准备压缩文本,原始大小: ${sourceData.byteLength} 字节,内容长度: ${text.length} 字符`);
    
    // 执行压缩
    const compressedData = await compressData(sourceData);
    
    return compressedData;
  } catch (error) {
    console.error(`字符串压缩失败: ${error}`);
    throw error;
  }
}

/**
 * 解压字符串数据
 * @param compressedData 压缩后的数据
 * @returns Promise<string> 解压后的文本字符串
 */
async function decompressString(compressedData: ArrayBuffer): Promise<string> {
  try {
    // 执行解压
    const decompressedData = await decompressData(compressedData);
    
    // 将ArrayBuffer转换回字符串
    const decoder = new TextDecoder();
    const text = decoder.decode(decompressedData);
    
    console.log(`解压文本完成,恢复内容长度: ${text.length} 字符`);
    
    return text;
  } catch (error) {
    console.error(`字符串解压失败: ${error}`);
    throw error;
  }
}

2. 文件压缩与解压

2.1 单文件压缩处理

文件压缩是压缩技术的重要应用场景,特别适用于处理大型文件和批量文件操作:

/**
 * 压缩单个文件
 * @param inputFilePath 输入文件路径
 * @param outputFilePath 输出压缩文件路径
 * @returns Promise<boolean> 压缩是否成功
 */
async function compressFile(inputFilePath: string, outputFilePath: string): Promise<boolean> {
  try {
    // 配置压缩选项
    const options: zlib.Options = {
      level: zlib.CompressLevel.COMPRESS_LEVEL_BEST_COMPRESSION,  // 使用最佳压缩率
      memLevel: zlib.MemLevel.MEM_LEVEL_MAX,                     // 使用最大内存级别
      strategy: zlib.CompressStrategy.COMPRESS_STRATEGY_DEFAULT_STRATEGY
    };
    
    // 获取原文件信息
    const fileStats = await fs.stat(inputFilePath);
    const originalSize = fileStats.size;
    
    console.log(`开始压缩文件: ${inputFilePath},原始大小: ${originalSize} 字节`);
    
    // 执行文件压缩
    await zlib.compressFile(inputFilePath, outputFilePath, options);
    
    // 获取压缩后文件信息
    const compressedStats = await fs.stat(outputFilePath);
    const compressedSize = compressedStats.size;
    const compressionRatio = ((originalSize - compressedSize) / originalSize * 100).toFixed(2);
    
    console.log(`文件压缩完成: ${outputFilePath}`);
    console.log(`压缩效果: 原始 ${originalSize} 字节 -> 压缩后 ${compressedSize} 字节,节省空间 ${compressionRatio}%`);
    
    return true;
  } catch (error) {
    const err = error as BusinessError;
    console.error(`文件压缩失败,错误信息: ${err.message}`);
    return false;
  }
}

2.2 文件解压处理

对应的文件解压功能实现:

/**
 * 解压单个文件
 * @param compressedFilePath 压缩文件路径
 * @param outputFilePath 输出解压文件路径
 * @returns Promise<boolean> 解压是否成功
 */
async function decompressFile(compressedFilePath: string, outputFilePath: string): Promise<boolean> {
  try {
    // 配置解压选项
    const options: zlib.Options = {
      level: zlib.CompressLevel.COMPRESS_LEVEL_DEFAULT_COMPRESSION,
      memLevel: zlib.MemLevel.MEM_LEVEL_DEFAULT,
      strategy: zlib.CompressStrategy.COMPRESS_STRATEGY_DEFAULT_STRATEGY
    };
    
    console.log(`开始解压文件: ${compressedFilePath}`);
    
    // 执行文件解压
    await zlib.decompressFile(compressedFilePath, outputFilePath, options);
    
    // 验证解压结果
    const decompressedStats = await fs.stat(outputFilePath);
    console.log(`文件解压完成: ${outputFilePath},文件大小: ${decompressedStats.size} 字节`);
    
    return true;
  } catch (error) {
    const err = error as BusinessError;
    console.error(`文件解压失败,错误信息: ${err.message}`);
    return false;
  }
}

3. 高级压缩技术

3.1 分块压缩处理

对于大型文件,分块压缩可以有效控制内存使用并提供进度反馈:

/**
 * 分块压缩大文件
 * @param inputFilePath 输入文件路径
 * @param outputFilePath 输出文件路径
 * @param chunkSize 分块大小(字节)
 * @param progressCallback 进度回调函数
 */
async function compressFileInChunks(
  inputFilePath: string, 
  outputFilePath: string, 
  chunkSize: number = 1024 * 1024, // 默认1MB分块
  progressCallback?: (progress: number) => void
): Promise<void> {
  try {
    const fileStats = await fs.stat(inputFilePath);
    const totalSize = fileStats.size;
    let processedSize = 0;
    
    // 打开输入和输出文件
    const inputFile = await fs.open(inputFilePath, fs.OpenMode.READ_ONLY);
    const outputFile = await fs.open(outputFilePath, fs.OpenMode.WRITE_ONLY | fs.OpenMode.CREATE);
    
    console.log(`开始分块压缩,文件大小: ${totalSize} 字节,分块大小: ${chunkSize} 字节`);
    
    while (processedSize < totalSize) {
      const remainingSize = totalSize - processedSize;
      const currentChunkSize = Math.min(chunkSize, remainingSize);
      
      // 读取数据块
      const buffer = new ArrayBuffer(currentChunkSize);
      await fs.read(inputFile.fd, buffer, { offset: processedSize });
      
      // 压缩数据块
      const compressedChunk = await compressData(buffer);
      
      // 写入压缩数据
      await fs.write(outputFile.fd, compressedChunk);
      
      processedSize += currentChunkSize;
      
      // 更新进度
      const progress = (processedSize / totalSize) * 100;
      if (progressCallback) {
        progressCallback(progress);
      }
      
      console.log(`压缩进度: ${progress.toFixed(1)}%`);
    }
    
    // 关闭文件
    await fs.close(inputFile.fd);
    await fs.close(outputFile.fd);
    
    console.log('分块压缩完成');
  } catch (error) {
    console.error(`分块压缩失败: ${error}`);
    throw error;
  }
}

通过本篇的学习,开发者已经掌握了鸿蒙压缩解压技术的核心API使用方法,包括数据压缩、文件压缩、分块处理等关键技术。这些技术为构建高效的移动应用提供了强有力的支持。

收藏00

登录 后评论。没有帐号? 注册 一个。