Flutter for OpenHarmony:convert 高效的二进制编码解码器,轻松处理 Hex、JSON、Base64(数据格式转换) 深度解析与鸿蒙适配指南
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.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 (数据槽):用于流式处理数据,适合大文件或网络流。
'48656c6c6f' (十六进制字符串)
hex.decode
72, 101, 108, 108, 111
hex.encode
1.2 进阶概念
该库遵循 dart:convert 的设计模式,这意味着它可以无缝集成到 Stream.transform 管道中。
二、核心 API/组件详解
2.1 基础用法
处理 Hex 字符串。
import'package:convert/convert.dart';voidmain(){// 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';voidprocessStream(){// 模拟一个不断产生 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 端需将其转为可读字符串或对象。
voidonBleDataReceived(List<int> data){// 假设前 2 字节是标志位String hexStr = hex.encode(data);print('Received raw hex: $hexStr');}3.2 场景 2:加密密钥存储
AES/RSA 密钥通常以 Hex 或 Base64 形式存储在本地文件或数据库中。
voidsaveKey(List<int> keyBytes)async{// 转为 Hex 字符串存储,通过 secure_storagefinal keyHex = hex.encode(keyBytes);await storage.write(key:'aes_key', value: keyHex);}3.3 场景 3:自定义协议解析
解析 Socket 接收到的定长包头(如前 4 字节为长度,后续为 JSON 体)。
voidparsePacket(List<int> packet){// 取前4字节的 HexString 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';voidmain(){runApp(constMaterialApp(home:ConverterPage()));}classConverterPageextendsStatefulWidget{constConverterPage({super.key});@overrideState<ConverterPage>createState()=>_ConverterPageState();}class _ConverterPageState extendsState<ConverterPage>{final _textController =TextEditingController();final _hexController =TextEditingController();String _error ='';void_onTextChanged(String text){try{// String -> UTF8 Bytes -> Hex Stringvar 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 Stringvar 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 格式');}}@overrideWidgetbuild(BuildContext context){returnScaffold( appBar:AppBar(title:constText('Hex 转换工具')), body:Padding( padding:constEdgeInsets.all(16.0), child:Column( children:[TextField( controller: _textController, decoration:constInputDecoration( labelText:'普通文本 (UTF-8)', border:OutlineInputBorder(),), onChanged: _onTextChanged,),constSizedBox(height:20),constIcon(Icons.swap_vert, size:32, color:Colors.blue),constSizedBox(height:20),TextField( controller: _hexController, decoration:InputDecoration( labelText:'十六进制 (Hex)', border:constOutlineInputBorder(), errorText: _error.isNotEmpty ? _error :null,), onChanged: _onHexChanged, keyboardType:TextInputType.text,// Hex contains a-f),],),),);}}
六、总结
convert 库极其轻量,却解决了 Dart 标准库在这方面的缺失。
最佳实践:
- 异常捕获:Hex 解码极易出错(比如长度是奇数),务必
try-catch。 - 区分大小写:通常 Hex 库能处理大小写,但规范输出时建议统一(如大写)。
- 流处理:处理文件流时优先使用
Stream.transform(hex.decoder),而非一次性读取内存。