• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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&lt;void&gt; | 压缩文件。               |
18| decompressFile(inFile: string, outFile: string, options?: Options): Promise&lt;void&gt; | 解压文件。               |
19| compress(dest: ArrayBuffer, source: ArrayBuffer, sourceLen?: number): Promise&lt;ZipOutputInfo&gt; | 将源缓冲区压缩到目标缓冲区。               |
20| compressBound(sourceLen: number): Promise&lt;number&gt; | 计算返回压缩大小的上限。              |
21| uncompress(dest:ArrayBuffer, source: ArrayBuffer, sourceLen?: number): Promise&lt;ZipOutputInfo&gt; | 将压缩后的数据解压缩为原始的未压缩形式。               |
22| deflate(strm: ZStream, flush: CompressFlushMode): Promise&lt;ReturnStatus&gt; | 压缩数据。               |
23| inflate(strm: ZStream, flush: CompressFlushMode): Promise&lt;ReturnStatus&gt; | 解压数据。|
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-传入的缓冲区错误)。