ZetCode

Dart ZLibDecoder

最后修改于 2025 年 4 月 4 日

Dart 中的 ZLibDecoder 类提供了解压缩使用 zlib 格式压缩的数据的功能。它是 Dart 的 dart:iodart:convert 库的一部分。

ZLibDecoder 处理 zlib 编码的数据流的解压缩,这在网络协议和文件压缩中很常用。它支持原始和包装的 zlib 流。

基本定义

ZLibDecoder 是一个转换器,它将 zlib 压缩的字节数据转换为其原始未压缩的形式。它实现了用于流处理的 Codec 接口。

主要功能包括支持流式解压缩、内存效率以及处理 zlib 包装和原始压缩数据格式。

ZLibDecoder 基本用法

此示例显示了 zlib 压缩字节列表的基本解压缩。

main.dart
import 'dart:convert';

void main() {
  // Compressed data (zlib format)
  final compressed = [120, 156, 75, 76, 74, 6, 0, 2, 130, 1, 69];
  
  final decoder = ZLibDecoder();
  final decompressed = decoder.convert(compressed);
  
  print('Decompressed: ${String.fromCharCodes(decompressed)}');
}

我们创建了一个 ZLibDecoder 实例,并使用其 convert 方法解压缩字节列表。压缩数据代表 zlib 格式的字符串“Hello”。

$ dart main.dart
Decompressed: Hello

流式解压缩

此示例演示了 zlib 数据的流式解压缩。

main.dart
import 'dart:convert';
import 'dart:async';

Future<void> main() async {
  // Simulate streaming compressed data
  final stream = Stream.fromIterable([
    [120, 156],
    [75, 76, 74, 6],
    [0, 2, 130, 1, 69]
  ]);
  
  final decoder = ZLibDecoder();
  final decompressed = await decoder.bind(stream).toList();
  
  final result = decompressed.expand((x) => x).toList();
  print('Decompressed: ${String.fromCharCodes(result)}');
}

我们使用 bind 方法将压缩数据块的流连接到解码器。这对于大型压缩数据流非常节省内存。

$ dart main.dart
Decompressed: Hello

处理原始 ZLib 数据

此示例显示了如何解压缩没有头的原始 zlib 数据。

main.dart
import 'dart:convert';

void main() {
  // Raw compressed data (no zlib headers)
  final rawCompressed = [75, 76, 74, 6, 0, 2, 130, 1, 69];
  
  final decoder = ZLibDecoder(raw: true);
  final decompressed = decoder.convert(rawCompressed);
  
  print('Decompressed: ${String.fromCharCodes(decompressed)}');
}

通过将 raw 参数设置为 true,我们告诉解码器期望没有 zlib 头的原始压缩数据。这对于某些协议很有用。

$ dart main.dart
Decompressed: Hello

错误处理

此示例演示了在解压缩期间正确的错误处理。

main.dart
import 'dart:convert';

void main() {
  // Invalid compressed data
  final invalidData = [1, 2, 3, 4, 5];
  
  final decoder = ZLibDecoder();
  
  try {
    final decompressed = decoder.convert(invalidData);
    print('Decompressed: $decompressed');
  } on FormatException catch (e) {
    print('Decompression failed: ${e.message}');
  }
}

我们将解压缩包装在 try-catch 块中,以处理无效压缩数据可能发生的 FormatExceptions。

$ dart main.dart
Decompression failed: Invalid zlib data

解压缩大文件

此示例显示了如何高效地解压缩大型 zlib 压缩文件。

main.dart
import 'dart:io';
import 'dart:convert';

Future<void> main() async {
  final inputFile = File('compressed.zlib');
  final outputFile = File('decompressed.txt');
  
  final decoder = ZLibDecoder();
  
  await outputFile.openWrite().addStream(
    inputFile.openRead().transform(decoder)
  );
  
  print('File decompressed successfully');
}

我们使用文件流和 transform 方法来解压缩大文件,而无需将整个内容加载到内存中。这对于大文件非常节省内存。

$ dart main.dart
File decompressed successfully

最佳实践

来源

Dart ZLibDecoder 文档

本教程介绍了 Dart 的 ZLibDecoder 类,并通过实际示例展示了基本解压缩、流式处理、错误处理和文件操作。

作者

我的名字是 Jan Bodnar,我是一名热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。到目前为止,我已撰写了 1400 多篇文章和 8 本电子书。我在教学编程方面拥有十多年的经验。

列出 所有 Dart 教程