1# 压缩与解压 2<!--Kit: Ability Kit--> 3<!--Subsystem: BundleManager--> 4<!--Owner: @jinsenjun--> 5<!--Designer: @jinsenjun--> 6<!--Tester: @lixueqing--> 7<!--Adviser: @Brilliantry_Rui--> 8 9本文针对常见的几种压缩、解压场景,介绍相关函数的使用方法。 10 11## 接口说明 12 13以下是示例中使用的主要接口,更多接口及使用方式请见[接口文档](../../reference/apis-basic-services-kit/js-apis-zlib.md)。 14 15| 接口名 | 接口描述 | 16| ------------------------------------------------------------ | ---------------------------- | 17| compressFile(inFile: string, outFile: string, options: Options): Promise<void> | 压缩文件。 | 18| decompressFile(inFile: string, outFile: string, options?: Options): Promise<void> | 解压文件。 | 19| compress(dest: ArrayBuffer, source: ArrayBuffer, sourceLen?: number): Promise<ZipOutputInfo> | 将源缓冲区压缩到目标缓冲区。 | 20| compressBound(sourceLen: number): Promise<number> | 计算返回压缩大小的上限。 | 21| uncompress(dest:ArrayBuffer, source: ArrayBuffer, sourceLen?: number): Promise<ZipOutputInfo> | 将压缩后的数据解压缩为原始的未压缩形式。 | 22| deflate(strm: ZStream, flush: CompressFlushMode): Promise<ReturnStatus> | 压缩数据。 | 23| inflate(strm: ZStream, flush: CompressFlushMode): Promise<ReturnStatus> | 解压数据。| 24 25## 开发步骤 26 27### 环境准备 28 29在应用沙箱目录下创建一个测试文件data.txt,并写入测试数据。示例代码如下。 30 31 ```ts 32 import { fileIo as fs} from '@kit.CoreFileKit'; 33 import { BusinessError, zlib } from '@kit.BasicServicesKit'; 34 35 @Entry 36 @Component 37 struct Index { 38 @State dataSize: number = 0; 39 40 build() { 41 Row() { 42 Column() { 43 // 在应用沙箱目录下创建文件data.txt,并写入测试数据 44 Button('创建测试文件data.txt').onClick(() => { 45 let path = this.getUIContext()?.getHostContext()?.filesDir; 46 // 创建文件data.txt 47 let inFile = fs.openSync(path + '/data.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 48 // 写入测试数据 49 for (let index = 0; index < 100; index++) { 50 fs.writeSync(inFile.fd, index + ': hello world, hello world, hello world, hello world, hello world.\n'); 51 } 52 // 获取测试数据原始大小,并保存到dataSize中 53 let stat = fs.statSync(inFile.path); 54 this.dataSize = stat.size; 55 console.info('dataSize: ' + this.dataSize); 56 // 关闭文件 57 fs.closeSync(inFile); 58 }) 59 } 60 } 61 .height('100%') 62 .width('100%') 63 } 64 } 65 ``` 66 67### Zip文件的压缩与解压 68 69采用接口[zlib.compressFile()](../../reference/apis-basic-services-kit/js-apis-zlib.md#zlibcompressfile9-1)将文件data.txt压缩并归档到data.zip中,采用接口[zlib.decompressFile()](../../reference/apis-basic-services-kit/js-apis-zlib.md#zlibdecompressfile9-1)将data.zip解压到应用沙箱目录下,示例代码如下。 70 71 ```ts 72 import { fileIo as fs} from '@kit.CoreFileKit'; 73 import { BusinessError, zlib } from '@kit.BasicServicesKit'; 74 75 @Entry 76 @Component 77 struct Index { 78 build() { 79 Row() { 80 // 示例一:将测试文件data.txt压缩并归档到data.zip中。 81 Button('compressFile').onClick(() => { 82 let path = this.getUIContext()?.getHostContext()?.filesDir; 83 let inFile = path + '/data.txt'; 84 let outFile = path + '/data.zip'; 85 let options: zlib.Options = {}; 86 zlib.compressFile(inFile, outFile, options).then((data: void) => { 87 console.info('compressFile success, data: ' + JSON.stringify(data)); 88 }).catch((errData: BusinessError) => { 89 console.error(`compressFile errCode: ${errData.code}, message: ${errData.message}`); 90 }) 91 }) 92 93 // 示例二:将data.zip文件解压到应用沙箱目录下。 94 Button('decompressFile').onClick(() => { 95 let path = this.getUIContext()?.getHostContext()?.filesDir; 96 let inFile = path + '/data.zip'; 97 let outFile = path; 98 let options: zlib.Options = {}; 99 zlib.decompressFile(inFile, outFile, options).then((data: void) => { 100 console.info('decompressFile success, data: ' + JSON.stringify(data)); 101 }).catch((errData: BusinessError) => { 102 console.error(`decompressFile errCode: ${errData.code}, message: ${errData.message}`); 103 }) 104 }) 105 } 106 .height('100%') 107 .width('100%') 108 } 109 } 110 ``` 111 112### 已知大小缓冲区的压缩与解压 113 114针对一个已知大小的缓冲区中的数据,使用接口[compress()](../../reference/apis-basic-services-kit/js-apis-zlib.md#compress12)将其压缩到一个目的缓冲区中,使用接口[compressBound()](../../reference/apis-basic-services-kit/js-apis-zlib.md#compressbound12)计算压缩目的缓冲区大小的上限值,使用接口[uncompress()](../../reference/apis-basic-services-kit/js-apis-zlib.md#uncompress12)对存储压缩数据的缓冲区进行解压。由于解压时无法获取解压后原始数据的大小,为了确认解压后目的缓冲区的大小,需要在压缩前获取原始数据的大小并保存,示例代码如下。 115 116 ```ts 117 import { fileIo as fs} from '@kit.CoreFileKit'; 118 import { BusinessError, zlib } from '@kit.BasicServicesKit'; 119 120 @Entry 121 @Component 122 struct Index { 123 @State dataSize: number = 0; //用于保存原始数据的大小 124 125 build() { 126 Row() { 127 // 示例一:读取data.txt文件内容并存入一个缓冲区,调用compress接口压缩缓冲区中的数据到目标缓冲区,并将目标缓冲区的内容写入文件data.bin 128 Button('compress buffer').onClick(() => { 129 let path = this.getUIContext()?.getHostContext()?.filesDir; 130 let inFile = fs.openSync(path + '/data.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 131 let outFile = fs.openSync(path + '/data.bin', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 132 // 读取data.txt文件的内容,并存入缓冲区inBuf 133 let stat = fs.statSync(inFile.path); 134 let inBuf = new ArrayBuffer(stat.size); 135 let readLen = fs.readSync(inFile.fd, inBuf); 136 console.info(`original size: ${stat.size}, read len: ${readLen}`); 137 // 获取原始数据的大小,并保存 138 this.dataSize = stat.size; 139 // 创建一个压缩对象实例 140 let zip = zlib.createZipSync(); 141 // 获取一个目标缓冲区的上限 142 zip.compressBound(stat.size).then((data) => { 143 console.info(`the max dest buf len is ${data}`); 144 // 目标缓冲区outBuf 145 let outBuf = new ArrayBuffer(data); 146 // 将inBuf中的数据压缩到outBuf中 147 zip.compress(outBuf, inBuf, readLen).then((zipOutInfo) => { 148 console.info(`compress success, status ${zipOutInfo.status}, destLen ${zipOutInfo.destLen}`); 149 // 将outBuf中的数据写入到data.bin文件 150 let writeLen = fs.writeSync(outFile.fd, outBuf, { length: zipOutInfo.destLen }); 151 console.info(`write destBuf to data.bin, writeLen ${writeLen}`); 152 // 关闭文件 153 fs.closeSync(inFile.fd); 154 fs.closeSync(outFile.fd); 155 }).catch((errData: BusinessError) => { 156 console.error(`errData is errCode:${errData.code} message:${errData.message}`); 157 }) 158 }).catch((errData: BusinessError) => { 159 console.error(`errData is errCode:${errData.code} message:${errData.message}`); 160 }) 161 }) 162 163 // 示例二:读取data.bin文件中的压缩数据并存入一个缓冲区,调用uncompress接口将缓冲区中的数据解压到目标缓冲区,并将目标缓冲区的内容写入文件data.txt 164 Button('uncompress buffer').onClick(() => { 165 let path = this.getUIContext()?.getHostContext()?.filesDir; 166 let inFile = fs.openSync(path + '/data.bin', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 167 let outFile = fs.openSync(path + '/data.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 168 // 读取data.bin文件中的压缩数据,并存入缓冲区inBuf 169 let stat = fs.statSync(inFile.path); 170 let inBuf = new ArrayBuffer(stat.size); 171 let readLen = fs.readSync(inFile.fd, inBuf); 172 console.info(`compressed data size: ${stat.size}, read len: ${readLen}`); 173 // 创建一个目标缓冲区,此处的dataSize是我们进行数据压缩前保存的数据的原始大小 174 let outBuf = new ArrayBuffer(this.dataSize); 175 console.info(`the dest buf size is ${this.dataSize}`); 176 // 创建一个压缩对象实例 177 let zip = zlib.createZipSync(); 178 // 将inBuf中的数据解压缩outBuf中 179 zip.uncompress(outBuf, inBuf, readLen).then((zipOutInfo) => { 180 console.info(`uncompress success, status ${zipOutInfo.status}, destLen ${zipOutInfo.destLen}`); 181 // 将outBuf中的数据写入到data.txt文件 182 let writeLen = fs.writeSync(outFile.fd, outBuf, { length: zipOutInfo.destLen }); 183 console.info(`write destBuf to data.txt, writeLen ${writeLen}`); 184 // 关闭文件 185 fs.closeSync(inFile.fd); 186 fs.closeSync(outFile.fd); 187 }).catch((errData: BusinessError) => { 188 console.error(`errData is errCode:${errData.code} message:${errData.message}`); 189 }) 190 }) 191 } 192 .height('100%') 193 .width('100%') 194 } 195 } 196 ``` 197 198### 未知大小缓冲区的压缩与解压(zlib格式) 199 200针对一个未知大小的缓冲区中的数据,使用接口[deflate()](../../reference/apis-basic-services-kit/js-apis-zlib.md#deflate12)将从一个原始输入流中读取的数据进行压缩,使用接口[inflate()](../../reference/apis-basic-services-kit/js-apis-zlib.md#inflate12)将从一个压缩输入流中读取的数据进行解压,示例代码如下。 201 202 ```ts 203 import { fileIo as fs} from '@kit.CoreFileKit'; 204 import { BusinessError, zlib } from '@kit.BasicServicesKit'; 205 206 @Entry 207 @Component 208 struct Index { 209 build() { 210 Row() { 211 // 示例一:从文件中不断读取数据进行压缩 212 Button('deflateFile').onClick(() => { 213 let path = this.getUIContext()?.getHostContext()?.filesDir; 214 let inFile = fs.openSync(path + '/data.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 215 let outFile = fs.openSync(path + '/data.bin', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 216 deflateFile(inFile, outFile).then(() => { 217 console.info('deflateFile success'); 218 fs.closeSync(inFile.fd); 219 fs.closeSync(outFile.fd); 220 }) 221 }) 222 223 // 示例二:从文件中不断读取压缩数据进行解压 224 Button('inflateFile').onClick(() => { 225 let path = this.getUIContext()?.getHostContext()?.filesDir; 226 let inFile = fs.openSync(path + '/data.bin', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 227 let outFile = fs.openSync(path + '/data.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 228 inflateFile(inFile, outFile).then(() => { 229 console.info('deflateFile success'); 230 fs.closeSync(inFile.fd); 231 fs.closeSync(outFile.fd); 232 }) 233 }) 234 } 235 .height('100%') 236 .width('100%') 237 } 238 } 239 240 // 从一个文件中,不断的读入数据,进行压缩,并写入到另一个文件中 241 async function deflateFile(src: fs.File, dest: fs.File) { 242 let flush = zlib.CompressFlushMode.NO_FLUSH; 243 let strm: zlib.ZStream = {}; //初始化一个压缩流 244 const BUFLEN = 4096; 245 let inBuf = new ArrayBuffer(BUFLEN); // 初始化一个输入缓冲区 246 let outBuf = new ArrayBuffer(BUFLEN); // 初始化一个输出缓冲区 247 // 创建一个压缩对象实例 248 let zip = zlib.createZipSync(); 249 // 初始化流的状态 250 let initStatus = zip.deflateInit(strm, zlib.CompressLevel.COMPRESS_LEVEL_BEST_SPEED); 251 console.info('deflateInit ret: ' + (await initStatus).valueOf()); 252 do { 253 // 从文件中读取数据到缓冲区 254 let readLen = fs.readSync(src.fd, inBuf); 255 console.info("readSync readLen: " + readLen); 256 flush = readLen == 0 ? zlib.CompressFlushMode.FINISH : zlib.CompressFlushMode.NO_FLUSH; 257 // 设置输入缓冲区 258 strm.availableIn = readLen; 259 strm.nextIn = inBuf; 260 do { 261 // 设置输出缓冲区 262 strm.availableOut = BUFLEN; 263 strm.nextOut = outBuf; 264 try { 265 // 压缩输入缓冲区中数据到输出缓冲区 266 let deflateStatus = zip.deflate(strm, flush); 267 console.info('deflate ret: ' + (await deflateStatus).valueOf()); 268 // 更新流的状态 269 let innerStrm = zip.getZStream(); 270 strm.availableIn = (await innerStrm).availableIn; 271 strm.nextIn = (await innerStrm).nextIn; 272 strm.availableOut = (await innerStrm).availableOut; 273 strm.nextOut = (await innerStrm).nextOut; 274 strm.totalIn = (await innerStrm).totalIn; 275 strm.totalOut = (await innerStrm).totalOut; 276 277 if (strm.availableOut != undefined) { 278 // 将已完成压缩的数据,写入到输出文件中 279 let have = BUFLEN - strm.availableOut; 280 let writeLen = fs.writeSync(dest.fd, outBuf, { length: have }); 281 console.info(`writeSync writeLen: ${writeLen}`); 282 } 283 } catch (err) { 284 console.error('deflate err: ' + JSON.stringify(err)); 285 } 286 } while (strm.availableOut == 0); // 循环压缩输入缓冲区中剩余的数据,直到全部完成压缩 287 } while (flush != zlib.CompressFlushMode.FINISH); // 循环从文件中读取数据,直到数据全部读取 288 // 释放资源 289 zip.deflateEnd(strm); 290 } 291 292 // 从一个文件中,不断的读入已压缩的数据,进行解压,并写入到另一个文件中 293 async function inflateFile(src: fs.File, dest: fs.File) { 294 let status: zlib.ReturnStatus = zlib.ReturnStatus.OK; 295 let strm: zlib.ZStream = {}; //初始化一个压缩流 296 const BUFLEN = 4096; 297 let inBuf = new ArrayBuffer(BUFLEN); // 初始化一个输入缓冲区 298 let outBuf = new ArrayBuffer(BUFLEN); // 初始化一个输出缓冲区 299 // 创建一个压缩对象实例 300 let zip = zlib.createZipSync(); 301 // 初始化流的状态 302 let initStatus = zip.inflateInit(strm); 303 console.info('inflateInit ret: ' + (await initStatus).valueOf()); 304 do { 305 // 从文件中读取已压缩的数据到缓冲区 306 let readLen = fs.readSync(src.fd, inBuf); 307 console.info("readSync readLen: " + readLen); 308 if (readLen == 0) { 309 break; 310 } 311 // 设置输入缓冲区 312 strm.availableIn = readLen; 313 strm.nextIn = inBuf; 314 do { 315 // 设置输出缓冲区 316 strm.availableOut = BUFLEN; 317 strm.nextOut = outBuf; 318 try { 319 // 解压输入缓冲区中数据到输出缓冲区 320 let inflateStatus = zip.inflate(strm, zlib.CompressFlushMode.NO_FLUSH); 321 console.info('inflate ret: ' + (await inflateStatus).valueOf()); 322 status = await inflateStatus; 323 // 更新流的状态 324 let innerStrm = zip.getZStream(); 325 strm.availableIn = (await innerStrm).availableIn; 326 strm.nextIn = (await innerStrm).nextIn; 327 strm.availableOut = (await innerStrm).availableOut; 328 strm.nextOut = (await innerStrm).nextOut; 329 strm.totalIn = (await innerStrm).totalIn; 330 strm.totalOut = (await innerStrm).totalOut; 331 332 if (strm.availableOut != undefined) { 333 // 将已完成解压的数据,写入到输出文件中 334 let have = BUFLEN - strm.availableOut; 335 let writeLen = fs.writeSync(dest.fd, outBuf, { length: have }); 336 console.info(`writeSync writeLen: ${writeLen}`); 337 } 338 } catch (err) { 339 console.error('inflate err: ' + JSON.stringify(err)); 340 } 341 } while (strm.availableOut == 0) // 循环解压输入缓冲区中剩余的数据,直到全部完成解压 342 } while (status != zlib.ReturnStatus.STREAM_END.valueOf()) // 循环从文件中读取数据,直到数据全部读取 343 // 释放资源 344 zip.inflateEnd(strm); 345 } 346 ``` 347 348### 未知大小缓冲区的压缩与解压(gzip格式) 349 350采用gzip格式,针对一个未知大小的缓冲区中的数据,使用接口[deflate()](../../reference/apis-basic-services-kit/js-apis-zlib.md#deflate12)将从一个原始输入流中读取的数据进行压缩,使用接口[inflate()](../../reference/apis-basic-services-kit/js-apis-zlib.md#inflate12)将从一个压缩输入流中读取的数据进行解压,示例代码如下。 351 352 ```ts 353 import { fileIo as fs} from '@kit.CoreFileKit'; 354 import { BusinessError, zlib } from '@kit.BasicServicesKit'; 355 356 @Entry 357 @Component 358 struct Index { 359 build() { 360 Row() { 361 // 示例一:从文件中不断读取数据进行压缩 362 Button('deflateGzipFile').onClick(() => { 363 let path = this.getUIContext()?.getHostContext()?.filesDir; 364 let inFile = fs.openSync(path + '/data.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 365 let outFile = fs.openSync(path + '/data.gz', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 366 deflateGzipFile(inFile, outFile).then(() => { 367 console.info('deflateGzipFile success'); 368 fs.closeSync(inFile.fd); 369 fs.closeSync(outFile.fd); 370 }) 371 }) 372 373 // 示例二:从文件中不断读取压缩数据进行解压 374 Button('inflateGzipFile').onClick(() => { 375 let path = this.getUIContext()?.getHostContext()?.filesDir; 376 let inFile = fs.openSync(path + '/data.gz', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 377 let outFile = fs.openSync(path + '/data.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 378 inflateGzipFile(inFile, outFile).then(() => { 379 console.info('inflateGzipFile success'); 380 fs.closeSync(inFile.fd); 381 fs.closeSync(outFile.fd); 382 }) 383 }) 384 } 385 .height('100%') 386 .width('100%') 387 } 388 } 389 390 // 从一个文件中,不断的读入数据,进行压缩,并写入到另一个文件中 391 async function deflateGzipFile(src: fs.File, dest: fs.File) { 392 let flush = zlib.CompressFlushMode.NO_FLUSH; 393 let strm: zlib.ZStream = {}; //初始化一个压缩流 394 const BUFLEN = 4096; 395 let inBuf = new ArrayBuffer(BUFLEN); // 初始化一个输入缓冲区 396 let outBuf = new ArrayBuffer(BUFLEN); // 初始化一个输出缓冲区 397 // 创建一个压缩对象实例 398 let zip = zlib.createZipSync(); 399 // 初始化流的状态,windowBits > 15时,启用gzip格式 400 let windowBits = 15 + 16; 401 let initStatus = zip.deflateInit2(strm, zlib.CompressLevel.COMPRESS_LEVEL_BEST_SPEED, 402 zlib.CompressMethod.DEFLATED, windowBits, zlib.MemLevel.MEM_LEVEL_DEFAULT, 403 zlib.CompressStrategy.COMPRESS_STRATEGY_DEFAULT_STRATEGY); 404 console.info('deflateInit2 ret: ' + (await initStatus).valueOf()); 405 do { 406 // 从文件中读取数据到缓冲区 407 let readLen = fs.readSync(src.fd, inBuf); 408 console.info("readSync readLen: " + readLen); 409 flush = readLen == 0 ? zlib.CompressFlushMode.FINISH : zlib.CompressFlushMode.NO_FLUSH; 410 // 设置输入缓冲区 411 strm.availableIn = readLen; 412 strm.nextIn = inBuf; 413 do { 414 // 设置输出缓冲区 415 strm.availableOut = BUFLEN; 416 strm.nextOut = outBuf; 417 try { 418 // 压缩输入缓冲区中数据到输出缓冲区 419 let deflateStatus = zip.deflate(strm, flush); 420 console.info('deflate ret: ' + (await deflateStatus).valueOf()); 421 // 更新流的状态 422 let innerStrm = zip.getZStream(); 423 strm.availableIn = (await innerStrm).availableIn; 424 strm.nextIn = (await innerStrm).nextIn; 425 strm.availableOut = (await innerStrm).availableOut; 426 strm.nextOut = (await innerStrm).nextOut; 427 strm.totalIn = (await innerStrm).totalIn; 428 strm.totalOut = (await innerStrm).totalOut; 429 430 if (strm.availableOut != undefined) { 431 // 将已完成压缩的数据,写入到输出文件中 432 let have = BUFLEN - strm.availableOut; 433 let writeLen = fs.writeSync(dest.fd, outBuf, { length: have }); 434 console.info(`writeSync writeLen: ${writeLen}`); 435 } 436 } catch (err) { 437 console.error('deflate err: ' + JSON.stringify(err)); 438 } 439 } while (strm.availableOut == 0); // 循环压缩输入缓冲区中剩余的数据,直到全部完成压缩 440 } while (flush != zlib.CompressFlushMode.FINISH); // 循环从文件中读取数据,直到数据全部读取 441 // 释放资源 442 zip.deflateEnd(strm); 443 } 444 445 // 从一个文件中,不断的读入已压缩的数据,进行解压,并写入到另一个文件中 446 async function inflateGzipFile(src: fs.File, dest: fs.File) { 447 let status: zlib.ReturnStatus = zlib.ReturnStatus.OK; 448 let strm: zlib.ZStream = {}; //初始化一个压缩流 449 const BUFLEN = 4096; 450 let inBuf = new ArrayBuffer(BUFLEN); // 初始化一个输入缓冲区 451 let outBuf = new ArrayBuffer(BUFLEN); // 初始化一个输出缓冲区 452 // 创建一个压缩对象实例 453 let zip = zlib.createZipSync(); 454 // 初始化流的状态,windowBits > 15时,启用gzip格式 455 let windowBits = 15 + 16; 456 let initStatus = zip.inflateInit2(strm, windowBits); 457 console.info('inflateInit2 ret: ' + (await initStatus).valueOf()); 458 do { 459 // 从文件中读取已压缩的数据到缓冲区 460 let readLen = fs.readSync(src.fd, inBuf); 461 console.info("readSync readLen: " + readLen); 462 if (readLen == 0) { 463 break; 464 } 465 // 设置输入缓冲区 466 strm.availableIn = readLen; 467 strm.nextIn = inBuf; 468 do { 469 // 设置输出缓冲区 470 strm.availableOut = BUFLEN; 471 strm.nextOut = outBuf; 472 try { 473 // 解压输入缓冲区中数据到输出缓冲区 474 let inflateStatus = zip.inflate(strm, zlib.CompressFlushMode.NO_FLUSH); 475 console.info('inflate ret: ' + (await inflateStatus).valueOf()); 476 status = await inflateStatus; 477 // 更新流的状态 478 let innerStrm = zip.getZStream(); 479 strm.availableIn = (await innerStrm).availableIn; 480 strm.nextIn = (await innerStrm).nextIn; 481 strm.availableOut = (await innerStrm).availableOut; 482 strm.nextOut = (await innerStrm).nextOut; 483 strm.totalIn = (await innerStrm).totalIn; 484 strm.totalOut = (await innerStrm).totalOut; 485 486 if (strm.availableOut != undefined) { 487 // 将已完成解压的数据,写入到输出文件中 488 let have = BUFLEN - strm.availableOut; 489 let writeLen = fs.writeSync(dest.fd, outBuf, { length: have }); 490 console.info(`writeSync writeLen: ${writeLen}`); 491 } 492 } catch (err) { 493 console.error('inflate err: ' + JSON.stringify(err)); 494 } 495 } while (strm.availableOut == 0) // 循环解压输入缓冲区中剩余的数据,直到全部完成解压 496 } while (status != zlib.ReturnStatus.STREAM_END.valueOf()) // 循环从文件中读取数据,直到数据全部读取 497 // 释放资源 498 zip.inflateEnd(strm); 499 } 500 ``` 501 502## 常见问题 503 5041. 17800005 传入的数据错误 505 506 可能原因和处理步骤,请参见[错误码17800005](../../reference/apis-basic-services-kit/errorcode-zlib.md#17800005-传入的数据错误)。 507 5082. 17800007 传入的缓冲区错误 509 510 可能原因和处理步骤,请参见[错误码17800007](../../reference/apis-basic-services-kit/errorcode-zlib.md#17800007-传入的缓冲区错误)。