Flutter for OpenHarmony:convert 高效的二进制编码解码器,轻松处理 Hex、JSON、Base64(数据格式转换) 深度解析与鸿蒙适配指南
摘要: convert 是 Dart 官方维护的增强转换库,弥补了标准库在处理十六进制字符串、Base64 变体等编码时的不足。它提供 Codec、Converter 和 Sink 等核心组件,支持双向转换和流式处理,适用于蓝牙通信、加密密钥存储和自定义协议解析等场景。该库纯 Dart 实现,可直接用于 OpenHarmony 平台,并通过 Stream.transform 或 compute 优
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
前言
在数据传输、加密解密、文件读写等底层操作中,二进制数据的转换是家常便饭。Flutter (Dart) 核心库虽然内置了 dart:convert (JSON/UTF8),但在处理十六进制 (Hex) 字符串、非常规 Base64 变体或其他编码时略显力不从心。
convert 是 Dart 官方维护的一个增强转换库,它提供了大量实用的 Codec, Converter, Sink 实现,填补了标准库在常见编码格式上的空白,尤其在处理自定义协议报文时极为便利。
一、概念介绍/原理解析
1.1 核心概念
- Codec (编解码器): 包含
Encoder和Decoder,如hex对象即为一个 Codec。 - Converter (转换器): 单向转换,如
hex.decoder将字符串转为字节列表。 - Sink (数据槽):用于流式处理数据,适合大文件或网络流。
1.2 进阶概念
该库遵循 dart:convert 的设计模式,这意味着它可以无缝集成到 Stream.transform 管道中。
二、核心 API/组件详解
2.1 基础用法
处理 Hex 字符串。
import 'package:convert/convert.dart';
void main() {
// 1. Hex 编码 (Bytes -> String)
var bytes = [0x48, 0x65, 0x6c, 0x6c, 0x6f]; // "Hello"
var hexString = hex.encode(bytes);
print(hexString); // "48656c6c6f"
// 2. Hex 解码 (String -> Bytes)
var decoded = hex.decode('48656c6c6f');
print(decoded); // [72, 101, 108, 108, 111]
}

2.2 流式转换 (Stream)
处理大文件或网络流时,使用 transform 更加高效。
import 'dart:async';
import 'package:convert/convert.dart';
void processStream() {
// 模拟一个不断产生 Hex 字符串的流
var stream = Stream.fromIterable(['48', '65', '6c', '6c', '6f']);
// 转换为字节流
stream.transform(hex.decoder).listen((byte) {
print('收到字节: $byte');
});
}

2.3 AccumulatorSink
累积数据直到处理这一块的全部内容。这在处理分块传输(Chunked Transfer)时很有用。
var sink = AccumulatorSink<String>();
sink.add('Part 1');
sink.add('Part 2');
sink.close();
print(sink.events); // ["Part 1", "Part 2"]
三、常见应用场景
3.1 场景 1:蓝牙/串口通信
低功耗蓝牙 (BLE) 设备传输的数通常是十六进制字节流,App 端需将其转为可读字符串或对象。
void onBleDataReceived(List<int> data) {
// 假设前 2 字节是标志位
String hexStr = hex.encode(data);
print('Received raw hex: $hexStr');
}
3.2 场景 2:加密密钥存储
AES/RSA 密钥通常以 Hex 或 Base64 形式存储在本地文件或数据库中。
void saveKey(List<int> keyBytes) async {
// 转为 Hex 字符串存储,通过 secure_storage
final keyHex = hex.encode(keyBytes);
await storage.write(key: 'aes_key', value: keyHex);
}
3.3 场景 3:自定义协议解析
解析 Socket 接收到的定长包头(如前 4 字节为长度,后续为 JSON 体)。
void parsePacket(List<int> packet) {
// 取前4字节的 Hex
String lenHex = hex.encode(packet.sublist(0, 4));
int len = int.parse(lenHex, radix: 16);
// ...
}
四、OpenHarmony 平台适配
4.1 纯算法库
convert 是纯 Dart 逻辑,无任何平台相关代码,在 OpenHarmony 上直接可用,无需配置。
4.2 性能优化
对于极大量数据的转换(如图片 Hex 转码),建议放入 compute (Isolate) 中执行,以免阻塞 UI 线程。
五、完整示例代码
本示例构建一个简单的 Hex 转换工具,用户输入字符串(如 “Hello”)或 Hex(如 “4865…”),实时显示另一种格式。
import 'dart:convert';
import 'package:convert/convert.dart'; // 是的,这里与 dart:convert 不冲突但需注意命名
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(home: ConverterPage()));
}
class ConverterPage extends StatefulWidget {
const ConverterPage({super.key});
State<ConverterPage> createState() => _ConverterPageState();
}
class _ConverterPageState extends State<ConverterPage> {
final _textController = TextEditingController();
final _hexController = TextEditingController();
String _error = '';
void _onTextChanged(String text) {
try {
// String -> UTF8 Bytes -> Hex String
var bytes = utf8.encode(text);
var hexStr = hex.encode(bytes);
_hexController.value = TextEditingValue(
text: hexStr,
selection: TextSelection.collapsed(offset: hexStr.length),
);
setState(() => _error = '');
} catch (e) {
// 一般不会错
}
}
void _onHexChanged(String text) {
try {
// 移除可能存在的空格
var cleanHex = text.replaceAll(' ', '');
// Hex String -> Bytes -> UTF8 String
var bytes = hex.decode(cleanHex);
var str = utf8.decode(bytes);
_textController.value = TextEditingValue(
text: str,
selection: TextSelection.collapsed(offset: str.length),
);
setState(() => _error = '');
} catch (e) {
setState(() => _error = '无效的 Hex 格式');
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Hex 转换工具')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextField(
controller: _textController,
decoration: const InputDecoration(
labelText: '普通文本 (UTF-8)',
border: OutlineInputBorder(),
),
onChanged: _onTextChanged,
),
const SizedBox(height: 20),
const Icon(Icons.swap_vert, size: 32, color: Colors.blue),
const SizedBox(height: 20),
TextField(
controller: _hexController,
decoration: InputDecoration(
labelText: '十六进制 (Hex)',
border: const OutlineInputBorder(),
errorText: _error.isNotEmpty ? _error : null,
),
onChanged: _onHexChanged,
keyboardType: TextInputType.text, // Hex contains a-f
),
],
),
),
);
}
}

六、总结
convert 库极其轻量,却解决了 Dart 标准库在这方面的缺失。
最佳实践:
- 异常捕获:Hex 解码极易出错(比如长度是奇数),务必
try-catch。 - 区分大小写:通常 Hex 库能处理大小写,但规范输出时建议统一(如大写)。
- 流处理:处理文件流时优先使用
Stream.transform(hex.decoder),而非一次性读取内存。
更多推荐


所有评论(0)