ZetCode

Dart ZLibEncoder

最后修改于 2025 年 4 月 4 日

Dart 中的 ZLibEncoder 类提供了 zlib 压缩功能。它对于减小存储或网络传输的数据量非常有用。

ZLibEncoder 实现 DEFLATE 压缩算法,带有 zlib 头和尾。它是 Dart 的 dart:iodart:zlib 库的一部分。

基本定义

ZLibEncoder 是一个转换器,使用 zlib 压缩字节数据。它支持不同的压缩级别,并生成标准的 zlib 格式输出。

主要功能包括可配置的压缩级别、流支持以及与其他 zlib 实现的兼容性。它对文本和二进制数据压缩效率很高。

ZLibEncoder 基本用法

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

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

void main() {
  final encoder = ZLibEncoder();
  final text = 'Hello, world! This is a test string for compression.';
  
  final compressed = encoder.encode(utf8.encode(text));
  print('Original size: ${text.length}');
  print('Compressed size: ${compressed.length}');
  print('Compression ratio: ${(compressed.length/text.length).toStringAsFixed(2)}');
}

我们创建一个 ZLibEncoder,对 UTF-8 字符串进行编码,并比较大小。编码器在默认设置下自动处理压缩过程。

$ dart main.dart
Original size: 47
Compressed size: 35
Compression ratio: 0.74

使用不同级别进行压缩

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

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

void main() {
  final text = 'Hello, world! '.codeUnits * 100; // Repeat 100 times
  final bytes = Uint8List.fromList(text);
  
  for (var level in [ZLibOption.minLevel, ZLibOption.defaultLevel, ZLibOption.maxLevel]) {
    final encoder = ZLibEncoder(level: level);
    final compressed = encoder.encode(bytes);
    
    print('Level $level: ${compressed.length} bytes');
  }
}

我们在重复的文本上测试不同的压缩级别。较高的级别通常会产生较小的输出,但压缩可能需要更多时间。

$ dart main.dart
Level 1: 60 bytes
Level 6: 56 bytes
Level 9: 56 bytes

流式压缩

此示例展示了如何使用 ZLibEncoder 压缩数据流。

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

Future<void> main() async {
  final encoder = ZLibEncoder();
  final controller = StreamController<List<int>>();
  
  // Create a stream of data chunks
  final stream = controller.stream;
  controller.add(utf8.encode('First chunk of data '));
  controller.add(utf8.encode('Second chunk of data '));
  controller.add(utf8.encode('Third chunk of data'));
  await controller.close();
  
  // Compress the stream
  final compressedStream = stream.transform(encoder);
  
  // Collect compressed data
  final compressedBytes = await compressedStream.toList();
  final totalSize = compressedBytes.fold(0, (sum, chunk) => sum + chunk.length);
  
  print('Compressed size: $totalSize bytes');
}

我们创建一个数据块流,并使用 ZLibEncoder 作为流转换器来压缩它们。这对于无法一次性载入内存的大型数据非常高效。

$ dart main.dart
Compressed size: 53 bytes

文件压缩

此示例演示了使用 ZLibEncoder 压缩文件的内容。

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

Future<void> main() async {
  final file = File('example.txt');
  final encoder = ZLibEncoder(level: ZLibOption.maxLevel);
  
  // Read file contents
  final contents = await file.readAsBytes();
  print('Original size: ${contents.length} bytes');
  
  // Compress contents
  final compressed = encoder.encode(contents);
  print('Compressed size: ${compressed.length} bytes');
  
  // Write compressed data to new file
  final compressedFile = File('example.txt.z');
  await compressedFile.writeAsBytes(compressed);
  print('Compressed file written');
}

我们读取一个文件,以最大压缩级别压缩其内容,然后将压缩后的数据写入新文件。这展示了实际的文件压缩用法。

$ dart main.dart
Original size: 1024 bytes
Compressed size: 543 bytes
Compressed file written

网络数据压缩

此示例展示了如何压缩用于网络传输的数据。

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

Future<void> main() async {
  final server = await HttpServer.bind('localhost', 8080);
  print('Server running on ${server.address}:${server.port}');
  
  await for (var request in server) {
    if (request.method == 'POST') {
      final encoder = ZLibEncoder();
      final data = await request.fold([], (list, chunk) => list..addAll(chunk));
      
      final compressed = encoder.encode(data);
      request.response
        ..headers.add('Content-Encoding', 'deflate')
        ..add(compressed)
        ..close();
    } else {
      request.response
        ..statusCode = HttpStatus.methodNotAllowed
        ..write('Only POST supported')
        ..close();
    }
  }
}

我们创建了一个简单的 HTTP 服务器,用于压缩 POST 数据响应。这可以减少网络带宽使用,同时保持数据完整性。

$ dart main.dart
Server running on InternetAddress('127.0.0.1', IPv4):8080

最佳实践

来源

Dart ZLibEncoder 文档

本教程介绍了 Dart 的 ZLibEncoder 类,并提供了实际示例,展示了基本用法、压缩级别、流处理以及文件/网络应用。

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 Dart 教程