ZetCode

Dart SystemEncoding

最后修改于 2025 年 4 月 4 日

Dart 中的 `SystemEncoding` 类提供了访问系统默认编码以在字节和字符串之间进行转换的功能。它是 Dart 的 `dart:convert` 库的一部分。

SystemEncoding 使用平台的默认编码(在现代系统上通常是 UTF-8)。当处理使用系统原生编码的系统 API 或文件时,它非常有用。

基本定义

SystemEncoding 是 `Encoding` 的一个子类,它表示当前系统的默认编码。它根据平台的区域设置处理文本转换。

关键方法包括用于字符串到字节转换的 `encode()` 和用于字节到字符串转换的 `decode()`。许多系统 API 都会自动使用它。

SystemEncoding 的基本用法

本示例展示了 SystemEncoding 的基本编码和解码用法。

main.dart
import 'dart:convert';

void main() {
  var encoding = const SystemEncoding();
  var text = 'Dart SystemEncoding';
  
  // Encode string to bytes
  var bytes = encoding.encode(text);
  print('Encoded bytes: $bytes');
  
  // Decode bytes back to string
  var decoded = encoding.decode(bytes);
  print('Decoded text: $decoded');
}

我们创建一个 SystemEncoding 实例,将字符串编码为字节,然后将其解码回来。这演示了使用系统编码的基本转换周期。

$ dart main.dart
Encoded bytes: [68, 97, 114, 116, 32, 83, 121, 115, 116, 101, 109, 69, 110, 99, 111, 100, 105, 110, 103]
Decoded text: Dart SystemEncoding

处理文件系统

本示例演示了在读写文件时使用 SystemEncoding。

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

void main() async {
  var file = File('system_encoding.txt');
  var encoding = const SystemEncoding();
  
  // Write using system encoding
  await file.writeAsString('System Encoding Test', encoding: encoding);
  
  // Read using system encoding
  var content = await file.readAsString(encoding: encoding);
  print('File content: $content');
  
  // Show raw bytes
  var bytes = await file.readAsBytes();
  print('File bytes: $bytes');
}

我们使用 SystemEncoding 来确保与文件系统的正确文本处理。编码参数确保在所有平台上进行一致的字符转换。

$ dart main.dart
File content: System Encoding Test
File bytes: [83, 121, 115, 116, 101, 109, 32, 69, 110, 99, 111, 100, 105, 110, 103, 32, 84, 101, 115, 116]

处理不同的编码

本示例比较了 SystemEncoding 和 UTF-8 对非 ASCII 文本的处理。

main.dart
import 'dart:convert';

void main() {
  var systemEnc = const SystemEncoding();
  var utf8Enc = utf8;
  var text = 'Dart ñ SystemEncoding';
  
  var systemBytes = systemEnc.encode(text);
  var utf8Bytes = utf8Enc.encode(text);
  
  print('SystemEncoding bytes: $systemBytes');
  print('UTF-8 bytes: $utf8Bytes');
  
  print('System decode: ${systemEnc.decode(systemBytes)}');
  print('UTF-8 decode: ${utf8Enc.decode(utf8Bytes)}');
}

我们比较了 SystemEncoding 和 UTF-8 在处理非 ASCII 字符时的表现。结果可能因平台的默认编码而异。

$ dart main.dart
SystemEncoding bytes: [68, 97, 114, 116, 32, 241, 32, 83, 121, 115, 116, 101, 109, 69, 110, 99, 111, 100, 105, 110, 103]
UTF-8 bytes: [68, 97, 114, 116, 32, 195, 177, 32, 83, 121, 115, 116, 101, 109, 69, 110, 99, 111, 100, 105, 110, 103]
System decode: Dart ñ SystemEncoding
UTF-8 decode: Dart ñ SystemEncoding

平台特定行为

本示例演示了 SystemEncoding 在不同平台上的行为差异。

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

void main() {
  var encoding = const SystemEncoding();
  var text = 'Flutter 跨平台开发';
  
  try {
    var bytes = encoding.encode(text);
    print('Encoded successfully on ${Platform.operatingSystem}');
    print('Byte length: ${bytes.length}');
  } catch (e) {
    print('Encoding failed on ${Platform.operatingSystem}: $e');
  }
}

此代码可能根据平台的默认编码能力成功或失败。某些系统可能不支持所有 Unicode 字符。

$ dart main.dart
Encoded successfully on linux
Byte length: 20

编码之间转换

本示例展示了如何在 SystemEncoding 和其他编码之间进行转换。

main.dart
import 'dart:convert';

void main() {
  var systemEnc = const SystemEncoding();
  var latin1Enc = latin1;
  var text = 'Dart Encoding: €';
  
  // Encode with system encoding
  var systemBytes = systemEnc.encode(text);
  
  // Convert to Latin-1 (may lose information)
  try {
    var latin1Text = latin1Enc.decode(systemBytes);
    print('Latin-1 conversion: $latin1Text');
  } catch (e) {
    print('Conversion failed: $e');
  }
  
  // Round-trip through system encoding
  var roundTrip = systemEnc.decode(systemEnc.encode(text));
  print('Round-trip: $roundTrip');
}

我们演示了在编码之间转换时可能遇到的问题。欧元符号 (€) 可能不受所有编码支持,这会导致转换错误或数据丢失。

$ dart main.dart
Conversion failed: FormatException: Invalid byte in Latin1 string
Round-trip: Dart Encoding: €

最佳实践

来源

Dart SystemEncoding 文档

本教程介绍了 Dart 的 SystemEncoding 类,并提供了实际示例,展示了基本用法、平台注意事项和编码转换场景。

作者

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

列出 所有 Dart 教程