ZetCode

Dart ZLibCodec

最后修改于 2025 年 4 月 4 日

Dart 中的 ZLibCodec 类提供了 zlib 压缩和解压缩功能。它对于减小存储或传输的数据量很有用。

ZLibCodec 使用 zlib 包装器实现了 DEFLATE 压缩算法。它是 Dart 的 dart:iodart:convert 库的一部分。

基本定义

ZLibCodec 是一种使用 zlib 格式压缩和解压缩字节数据的编解码器。它支持不同的压缩级别和策略。

主要功能包括可配置的压缩级别、流式支持以及与标准 zlib 实现的兼容性。它同时支持 List<int>Stream<List<int>> 数据。

基本压缩

此示例展示了使用 ZLibCodec 对字符串进行基本压缩。

main.dart
import 'dart:convert';

void main() {
  final codec = ZLibCodec();
  final text = 'The quick brown fox jumps over the lazy dog';
  
  final compressed = codec.encode(utf8.encode(text));
  print('Compressed: $compressed');
  
  final decompressed = utf8.decode(codec.decode(compressed));
  print('Decompressed: $decompressed');
}

我们创建一个 ZLibCodec 实例,将字符串编码为 UTF-8 字节,然后进行压缩。之后,将压缩数据解压缩回原始字符串。

$ dart main.dart
Compressed: [120, 156, 11, 201, 200, 44, 86, 0, 161, 52, 119, 23, 114, 233, 142, 6, 151, 128, 148, 210, 236, 146, 212, 226, 202, 212, 226, 140, 148, 210, 210, 156, 212, 18, 0, 237, 147, 15, 76]
Decompressed: The quick brown fox jumps over the lazy dog

带级别的压缩

此示例演示了使用不同的压缩级别。

main.dart
import 'dart:convert';

void main() {
  final text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
  final bytes = utf8.encode(text);
  
  for (var level = 1; level <= 9; level++) {
    final codec = ZLibCodec(level: level);
    final compressed = codec.encode(bytes);
    print('Level $level: ${compressed.length} bytes');
  }
}

我们测试从 1(最快)到 9(最佳压缩)的压缩级别。较高的级别通常会产生较小的输出,但压缩需要更多时间。

$ dart main.dart
Level 1: 63 bytes
Level 2: 57 bytes
Level 3: 56 bytes
Level 4: 55 bytes
Level 5: 55 bytes
Level 6: 55 bytes
Level 7: 55 bytes
Level 8: 55 bytes
Level 9: 55 bytes

文件压缩

此示例展示了文件的压缩和解压缩。

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

Future<void> main() async {
  final codec = ZLibCodec();
  final file = File('example.txt');
  
  // Compress file
  final original = await file.readAsBytes();
  final compressed = codec.encode(original);
  await File('example.z').writeAsBytes(compressed);
  
  // Decompress file
  final compressedFile = await File('example.z').readAsBytes();
  final decompressed = codec.decode(compressedFile);
  await File('example_decompressed.txt').writeAsBytes(decompressed);
  
  print('Original: ${original.length} bytes');
  print('Compressed: ${compressed.length} bytes');
}

我们读取一个文件,压缩其内容,然后保存压缩版本。接着,我们将其解压缩以验证过程。这展示了实际的文件压缩用法。

$ dart main.dart
Original: 1024 bytes
Compressed: 512 bytes

流式压缩

此示例演示了大型数据的流式压缩。

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

Future<void> main() async {
  final codec = ZLibCodec();
  final input = File('large_file.txt').openRead();
  final output = File('compressed.z').openWrite();
  
  // Compress stream
  await input.transform(codec.encoder).pipe(output);
  
  // Decompress stream
  final compressed = File('compressed.z').openRead();
  final decompressed = File('decompressed.txt').openWrite();
  await compressed.transform(codec.decoder).pipe(decompressed);
  
  print('Stream compression completed');
}

我们使用流来处理大文件,而无需将所有内容加载到内存中。transform 方法分块处理数据,使其具有内存效率。

$ dart main.dart
Stream compression completed

自定义字典

此示例展示了使用自定义字典进行压缩。

main.dart
import 'dart:convert';

void main() {
  final dictionary = utf8.encode('commonprefix');
  final codec = ZLibCodec(dictionary: dictionary);
  
  final text1 = 'commonprefix12345';
  final text2 = 'commonprefix67890';
  
  final compressed1 = codec.encode(utf8.encode(text1));
  final compressed2 = codec.encode(utf8.encode(text2));
  
  print('Text1 compressed: ${compressed1.length} bytes');
  print('Text2 compressed: ${compressed2.length} bytes');
  
  final decompressed1 = utf8.decode(codec.decode(compressed1));
  final decompressed2 = utf8.decode(codec.decode(compressed2));
  
  print('Decompressed1: $decompressed1');
  print('Decompressed2: $decompressed2');
}

自定义字典可以提高具有共同前缀的数据的压缩效率。编码器和解码器必须使用相同的字典才能正确运行。

$ dart main.dart
Text1 compressed: 22 bytes
Text2 compressed: 22 bytes
Decompressed1: commonprefix12345
Decompressed2: commonprefix67890

最佳实践

来源

Dart ZLibCodec 文档

本教程介绍了 Dart 的 ZLibCodec 类,并通过实际示例展示了基本用法、文件操作、流式处理以及字典等高级功能。

作者

我叫 Jan Bodnar,是一名热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有超过十年的经验。

列出 所有 Dart 教程