Flutter数据序列化与反序列化插件message_pack_dart的使用
Flutter数据序列化与反序列化插件message_pack_dart的使用
简介
messagePack_dart
是一个用于 Dart 和 Flutter 的 MessagePack 实现。MessagePack 是一种高效的二进制序列化格式,它可以在多种编程语言之间交换数据,类似于 JSON,但速度更快、体积更小。小整数可以编码为单个字节,短字符串也只需要额外一个字节。
安装
在 pubspec.yaml
文件中添加以下依赖:
dependencies:
message_pack_dart: ^latest_version
然后运行 flutter pub get
来安装插件。
示例代码
以下是一个完整的示例,展示了如何使用 message_pack_dart
进行数据的序列化和反序列化。这个示例包括了对不同数据类型的测试,并比较了 JSON 和 MessagePack 的性能。
import 'dart:convert';
import 'dart:io';
import 'package:message_pack_dart/message_pack_dart.dart' as m2;
const int TIMES = 10000;
// 辗转相除法计算最大公约数
gcd(num a, num b) => b != 0 ? gcd(b, a % b) : a;
class Fraction {
final num numerator;
final num denominator;
Fraction(this.numerator, this.denominator);
// 化简分数
Fraction reduce() {
var cd = gcd(numerator, denominator);
return Fraction(numerator / cd, denominator / cd);
}
// 交叉乘法
Fraction cross(Fraction other) => Fraction(
other.denominator * numerator, other.numerator * denominator);
[@override](/user/override)
String toString() => "${numerator}/${denominator}";
// 返回比例字符串
String toRatioString() => "${numerator}:${denominator}";
}
void main(List<String> args) async {
print("预热...");
for (var i = 0; i < TIMES; i++) {
var jsonStr = json.encode({"hello": "world"});
json.encode(json.decode(jsonStr));
}
if (args.contains("--savings")) {
var numbers = [];
for (var i = 1; i <= 100000; i++) {
numbers.add(i);
}
// 比较 JSON 和 MessagePack 的字节数
var jsonBytes = utf8.encode(json.encode(numbers)).length;
var msgpack2Bytes = m2.serialize(numbers).length;
print("JSON: ${jsonBytes} bytes, messagePack: ${msgpack2Bytes} bytes");
}
var objects = {
"One": 1,
"Five Hundred Thousand": 500000,
"List of Small Integers": [1, 2, 3],
"Simple Map": {"hello": "world"},
"5.02817472928": 5.02817472928,
"Multiple Type Map": {
"String": "Hello World",
"Integer": 1,
"Double": 2.0154,
"Array": const [1, 2, 3, "Hello"]
},
"Medium Data": {
"/downstream/wemo/CoffeeMaker-1_0-221421S0000731/Brew_Age": [
[1440366101049, -123881],
[1440366102047, -123882],
[1440366103049, -123883],
[1440366104046, -123884],
[1440366105062, -123885],
[1440366106050, -123886],
[1440366107046, -123887],
[1440366108045, -123888],
[1440366109036, -123889],
[1440366110048, -123890],
[1440366111047, -123891],
[1440366112037, -123892],
[1440366113048, -123893],
[1440366114048, -123894],
[1440366115046, -123895],
[1440366116044, -123896],
[1440366117045, -123897],
[1440366118049, -123898],
[1440366119046, -123899],
[1440366120042, -123900],
[1440366121047, -123901],
[1440366122048, -123902],
[1440366123046, -123903],
[1440366124055, -123904],
[1440366126059, -123906],
[1440366127054, -123907],
[1440366128047, -123908],
[1440366129051, -123909],
[1440366130051, -123910],
[1440366131048, -123911],
[1440366132050, -123912],
[1440366133032, -123913],
[1440366134045, -123914],
[1440366135050, -123915],
[1440366136049, -123916]
]
}
};
bool markdown = false;
if (args.contains("-m")) markdown = true;
if (args.contains("-u")) {
if (markdown) {
print("反序列化\n===");
} else {
print("=== 反序列化 ===");
}
for (var key in objects.keys) {
testObjectDecode(key, objects[key], markdown);
}
} else if (args.contains("-a")) {
if (markdown) {
print("序列化\n===");
} else {
print("=== 序列化 ===");
}
for (var key in objects.keys) {
testObjectEncode(key, objects[key], markdown);
}
if (markdown) {
print("反序列化\n===");
} else {
print("=== 反序列化 ===");
}
for (var key in objects.keys) {
testObjectDecode(key, objects[key], markdown);
}
} else {
if (markdown) {
print("序列化\n===");
} else {
print("=== 序列化 ===");
}
for (var key in objects.keys) {
testObjectEncode(key, objects[key], markdown);
}
}
}
void testObjectDecode(String desc, input, bool markdown) {
if (markdown) {
print('$desc\n---');
} else {
print("${desc}:");
}
var packedJson = json.encode(input);
var watch = Stopwatch();
var watchTotal = Stopwatch();
var times = [];
watchTotal.start();
for (var i = 1; i <= TIMES; i++) {
watch.reset();
watch.start();
json.decode(packedJson);
watch.stop();
times.add(watch.elapsedMicroseconds);
}
var totalTime = watchTotal.elapsedMicroseconds;
var avgTime = totalTime / TIMES;
times.sort((a, b) => a.compareTo(b));
if (!markdown) {
print(" JSON:");
print(" 总时间: $totalTime 微秒 (${totalTime / 1000}ms)");
print(" 平均时间: $avgTime 微秒 (${avgTime / 1000}ms)");
print(" 最长时间: ${times.last} 微秒 (${times.last / 1000}ms)");
print(" 最短时间: ${times.first} 微秒 (${times.first / 1000}ms)");
}
var jTotal = totalTime;
var jAvg = avgTime;
var jLong = times.last;
var jShort = times.first;
watch.reset();
times.clear();
watchTotal.reset();
for (var i = 1; i <= TIMES; i++) {
watch.reset();
watch.start();
m2.deserialize(m2.serialize(input));
watch.stop();
times.add(watch.elapsedMicroseconds);
}
totalTime = watchTotal.elapsedMicroseconds;
avgTime = totalTime / TIMES;
times.sort((a, b) => a.compareTo(b));
if (!markdown) {
print(" MsgPack2:");
print(" 总时间: ${totalTime} 微秒 (${totalTime / 1000}ms)");
print(" 平均时间: ${avgTime} 微秒 (${avgTime / 1000}ms)");
print(" 最长时间: ${times.last} 微秒 (${times.last / 1000}ms)");
print(" 最短时间: ${times.first} 微秒 (${times.first / 1000}ms)");
}
var nTotal = totalTime;
var nAvg = avgTime;
var nLong = times.last;
var nShort = times.first;
if (markdown) {
print("时间 | JSON | MsgPack2 | msgpack_dart |");
print("-----|------|----------|--------------|");
print("总时间 | $jTotal μs (${jTotal / 1000}ms) | " +
"$nTotal μs (${nTotal / 1000}ms) |" +
"$n2Total μs (${n2Total / 1000}ms)");
print("平均时间 | $jAvg μs (${jAvg / 1000}ms) | " +
"$nAvg μs (${nAvg / 1000}ms) |" +
"$n2Avg μs (${n2Avg / 1000}ms)");
print("最长时间 | $jLong μs (${jLong / 1000}ms) | " +
"$nLong μs (${nLong / 1000}ms) |" +
"$n2Long μs (${n2Long / 1000}ms)");
print("最短时间 | $jShort μs (${jShort / 1000}ms) | " +
"$nShort μs (${nShort / 1000}ms) |" +
"$n2Short μs (${n2Short / 1000}ms)");
}
var bestAvg = n2Avg;
String fastest = "msgpack_dart";
if (nAvg < bestAvg) {
bestAvg = nAvg;
fastest = "MsgPack2";
}
if (jAvg < bestAvg) {
bestAvg = jAvg;
fastest = "JSON";
}
if (markdown) {
print("最快 | $fastest\n");
} else {
print(" $fastest was fastest");
}
}
void testObjectEncode(String desc, input, bool markdown) {
if (markdown) {
print("$desc\n---");
} else {
print("${desc}:");
}
var watch = Stopwatch();
var watchTotal = Stopwatch();
var times = [];
watchTotal.start();
int size = utf8.encode(json.encode(input)).length;
for (var i = 1; i <= TIMES; i++) {
watch.reset();
watch.start();
json.encode(input);
watch.stop();
times.add(watch.elapsedMicroseconds);
}
var totalTime = watchTotal.elapsedMicroseconds;
var avgTime = totalTime / TIMES;
times.sort((a, b) => a.compareTo(b));
if (!markdown) {
print(" JSON:");
print(" 总时间: $totalTime 微秒 (${totalTime / 1000}ms)");
print(" 平均时间: $avgTime 微秒 (${avgTime / 1000}ms)");
print(" 最长时间: ${times.last} 微秒 (${times.last / 1000}ms)");
print(" 最短时间: ${times.first} 微秒 (${times.first / 1000}ms)");
print(" 大小: ${size} 字节");
}
var jTotal = totalTime;
var jAvg = avgTime;
var jLong = times.last;
var jShort = times.first;
var jSize = size;
watch.reset();
times.clear();
watchTotal.reset();
for (var i = 1; i <= TIMES; i++) {
watch.reset();
watch.start();
m2.serialize(input);
watch.stop();
times.add(watch.elapsedMicroseconds);
}
totalTime = watchTotal.elapsedMicroseconds;
avgTime = totalTime / TIMES;
times.sort((a, b) => a.compareTo(b));
if (!markdown) {
print(" MsgPack2:");
print(" 总时间: ${totalTime} 微秒 (${totalTime / 1000}ms)");
print(" 平均时间: ${avgTime} 微秒 (${avgTime / 1000}ms)");
print(" 最长时间: ${times.last} 微秒 (${times.last / 1000}ms)");
print(" 最短时间: ${times.first} 微秒 (${times.first / 1000}ms)");
print(" 大小: ${m2.serialize(input).length} 字节");
}
var nTotal = totalTime;
var nAvg = avgTime;
var nLong = times.last;
var nShort = times.first;
var nSize = m2.serialize(input).length;
if (markdown) {
print("时间 | JSON | MsgPack2 | msgpack_dart |");
print("-----|------|---------|--------------|");
print("总时间 | $jTotal μs (${jTotal / 1000}ms) | " +
"$nTotal μs (${nTotal / 1000}ms) | " +
"$n2Total μs (${n2Total / 1000}ms)");
print("平均时间 | $jAvg μs (${jAvg / 1000}ms) | " +
"$nAvg μs (${nAvg / 1000}ms) | " +
"$n2Avg μs (${n2Avg / 1000}ms)");
print("最长时间 | $jLong μs (${jLong / 1000}ms) | " +
"$nLong μs (${nLong / 1000}ms) | " +
"$n2Long μs (${n2Long / 1000}ms)");
print("最短时间 | $jShort μs (${jShort / 1000}ms) | " +
"$nShort μs (${nShort / 1000}ms) | " +
"$n2Short μs (${n2Short / 1000}ms)");
print("大小 | $jSize 字节 | $nSize 字节 | $n2Size 字节");
}
var bestAvg = n2Avg;
String fastest = "msgpack_dart";
if (nAvg < bestAvg) {
bestAvg = nAvg;
fastest = "MsgPack2";
}
if (jAvg < bestAvg) {
bestAvg = jAvg;
fastest = "JSON";
}
if (markdown) {
print("最快 | $fastest\n");
} else {
print(" $fastest was fastest");
}
}
更多关于Flutter数据序列化与反序列化插件message_pack_dart的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数据序列化与反序列化插件message_pack_dart的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter应用中,message_pack_dart
是一个用于数据序列化和反序列化的插件,它基于 MessagePack 格式,这是一种高效的二进制序列化格式。使用 message_pack_dart
可以方便地在 Flutter 应用中传输和存储数据。
以下是一个简单的示例,展示如何在 Flutter 中使用 message_pack_dart
插件进行数据序列化和反序列化。
首先,确保在 pubspec.yaml
文件中添加 message_pack_dart
依赖:
dependencies:
flutter:
sdk: flutter
message_pack_dart: ^2.0.0 # 请检查最新版本号
然后,运行 flutter pub get
来获取依赖。
接下来,编写 Dart 代码来演示序列化和反序列化过程:
import 'package:flutter/material.dart';
import 'package:message_pack_dart/message_pack.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('MessagePack Dart Demo'),
),
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
String serializedData = '';
Map<String, dynamic> deserializedData = {};
void serializeData() {
// 要序列化的数据
Map<String, dynamic> data = {
'name': 'Alice',
'age': 30,
'isStudent': false,
'scores': [95, 88, 92],
};
// 使用 MessagePack 序列化数据
var packer = MessagePack();
Uint8List packedData = packer.pack(data);
// 将序列化后的数据转换为 Base64 字符串以便显示
serializedData = base64Encode(packedData);
// 更新界面
setState(() {});
}
void deserializeData() {
if (serializedData.isEmpty) {
return;
}
// 将 Base64 字符串转换回 Uint8List
Uint8List packedData = base64Decode(serializedData);
// 使用 MessagePack 反序列化数据
var unpacker = MessagePack();
deserializedData = unpacker.unpack(packedData) as Map<String, dynamic>;
// 更新界面
setState(() {});
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: serializeData,
child: Text('Serialize Data'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: deserializeData,
child: Text('Deserialize Data'),
),
SizedBox(height: 40),
Text('Serialized Data (Base64):'),
Text(serializedData),
SizedBox(height: 20),
Text('Deserialized Data:'),
if (deserializedData.isNotEmpty)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Name: ${deserializedData['name']}'),
Text('Age: ${deserializedData['age']}'),
Text('Is Student: ${deserializedData['isStudent']}'),
Text('Scores: ${deserializedData['scores'].join(', ')}'),
],
),
],
);
}
}
在这个示例中,我们创建了一个简单的 Flutter 应用,其中包含一个用于序列化和反序列化数据的界面。我们定义了两个方法 serializeData
和 deserializeData
:
serializeData
方法将一个 Map 对象序列化为二进制数据,并将其转换为 Base64 字符串以便显示。deserializeData
方法将 Base64 字符串转换回二进制数据,并使用 MessagePack 反序列化回原始的 Map 对象。
运行这个应用,点击“Serialize Data”按钮将数据显示为序列化后的 Base64 字符串,点击“Deserialize Data”按钮将显示反序列化后的数据。