Flutter for OpenHarmony:convert 高效的二进制编码解码器,轻松处理 Hex、JSON、Base64(数据格式转换) 深度解析与鸿蒙适配指南

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 (编解码器): 包含 EncoderDecoder,如 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 标准库在这方面的缺失。

最佳实践

  1. 异常捕获:Hex 解码极易出错(比如长度是奇数),务必 try-catch
  2. 区分大小写:通常 Hex 库能处理大小写,但规范输出时建议统一(如大写)。
  3. 流处理:处理文件流时优先使用 Stream.transform(hex.decoder),而非一次性读取内存。

Read more

【算法】连通块问题(C/C++)

【算法】连通块问题(C/C++)

目录 连通块问题 解决思路 步骤: 初始化: DFS函数: 复杂度分析  代码实现(C++) 题目链接:2060. 奶牛选美 - AcWing题库 解题思路: AC代码:  题目链接:687. 扫雷 - AcWing题库  解题思路: AC代码: 总结: 连通块问题 连通块问题(Connected Component Problem)是一个经典的图论问题,通常用来找出图中的所有连通分量。给定一个无向图,连通块问题的目标是确定图中有多少个连通分量(即有多少个互相连通的节点组成的集合) 解决思路 1. 深度优先搜索(DFS) 或 广度优先搜索(BFS): * 可以从任意未访问的节点出发,进行DFS或BFS,标记所有能够访问到的节点,代表这个连通分量。 * 重复这个过程,直到所有节点都被访问为止。每次从新的未访问节点出发时,就代表发现了一个新的连通分量。 2.

By Ne0inhk
【C++:继承】C++面向对象继承全面解析:派生类构造、多继承、菱形虚拟继承与设计模式实践

【C++:继承】C++面向对象继承全面解析:派生类构造、多继承、菱形虚拟继承与设计模式实践

🔥艾莉丝努力练剑:个人主页 ❄专栏传送门:《C语言》、《数据结构与算法》、C/C++干货分享&学习过程记录、Linux操作系统编程详解、笔试/面试常见算法:从基础到进阶 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬艾莉丝的简介: 🎬艾莉丝的C++专栏简介: 目录 C++的两个参考文档 4  ~>  派生类的默认成员函数专题 4.4  实现一个不可继承类实现 4.4.1  间接实现:【C++98】构造函数私有的类不能被继承 4.4.2  直接实现:final关键字修改基类 4.4.3  代码实现 4.4.4  final关键字

By Ne0inhk
c++之inline关键字从基础到通天(一篇即毕业系列)

c++之inline关键字从基础到通天(一篇即毕业系列)

文章目录 * inline 是一个请求(而非命令) * inline 函数通常用于小函数 * inline 函数的定义通常放在头文件中 * inline 函数不能包含复杂的控制结构 * 编译器可能忽略 inline 请求 * 验证是否 inline * 代码块 * 汇编代码分析 * 其他验证方法 * 推荐阅读 欢迎收看一篇即毕业系列,本系列的其它内容如同本篇一样优秀喔!! 那么话不多说! 关于 inline,我们直接了解以下几个知识点即可。 inline 是一个请求(而非命令) inline 关键字用于向编译器发出一个请求,建议将函数体在每个调用点内联展开。这意味着编译器在编译过程中,可能会将函数的代码直接插入到调用该函数的地方,而不是通过通常的函数调用机制来执行。 需要注意的是,inline 只是一个建议,编译器可以选择是否接受这个建议。编译器可能会基于多种因素(如函数的大小、复杂性、调用频率以及整体代码的优化目标)来决定是否进行内联展开。 inline 函数通常用于小函数 inline 函数通常用于那些执行速度快且调用频繁的小

By Ne0inhk
从二叉树到 STL:揭开 set 容器的本质与用法

从二叉树到 STL:揭开 set 容器的本质与用法

前言:         上次介绍完二叉搜索树后,更新中断了一段时间,先向大家致歉。最近学习状态有些起伏,但我正在努力调整,相信很快会恢复节奏。今天我们继续深入探讨——关联容器,它在算法和工程中都非常常见和重要。 1.之前的遗漏         我之前写的二叉搜索树其实没有写完,我仅仅写了一个节点只能存储一个值的二叉搜索树。在我们日常的工作中,这种树的使用率其实还是比较低的。最受欢迎的是里面存储两个值的二叉搜索树,这个可以类比Python中的字典。相信学过python的读者对此不陌生,字典其实存放了一对值,分别是Key和Value,类比英文字典中的英语和汉字,我们通过英文(Key)来找到对应的中文(Value)。这其实才是我们常使用到的二叉搜索树,下面我通过举例来帮助各位理解这两棵树的区别。 1.1.Key搜索场景         举个例子,现在很多小区配有地下停车库。业主的车牌号会录入系统中,车辆进入时由系统识别并判断是否允许进入。这就是典型的 Key 搜索场景 —— 只需根据一个关键字(车牌号)进行查找。 1.2.Key/Value搜索场景         还是以我们

By Ne0inhk