Flutter数据序列化插件binary_serializable的使用

发布于 1周前 作者 nodeper 来自 Flutter

Flutter数据序列化插件binary_serializable的使用

高效地对二进制数据流进行序列化和反序列化。当与 binary_serializable_generator 结合使用时,可以方便地将 Dart 对象高效地编码为二进制数据,并将二进制流解码为 Dart 对象。

示例代码

以下是一个完整的示例代码,展示了如何使用 binary_serializable 插件来序列化和反序列化一个包含嵌套对象的数据结构。

import 'package:binary_serializable/binary_serializable.dart';

class Person {
  final String name;
  final int age;
  final List<Person> children;

  Person({required this.name, required this.age, required this.children});
}

void main() {
  // 创建一个示例对象
  final sample = Person(
    name: 'Alice',
    age: 87,
    children: [
      Person(
        name: 'Bob',
        age: 49,
        children: [
          Person(
            name: 'Tina',
            age: 17,
            children: [],
          ),
        ],
      ),
      Person(
        name: 'Joe',
        age: 49,
        children: [],
      ),
    ],
  );

  // 序列化对象
  final encoded = PersonType().encode(sample);

  // 打印编码后的二进制数据
  print(
    'Encoded data: ${encoded.map((b) => b.toRadixString(16).padLeft(2, '0')).join(' ')}',
  );

  // 反序列化二进制数据
  final decoded = PersonType().decode(encoded);

  // 打印解码后的数据
  print(
    '1st child of decoded sample: ${decoded.children.first.name} (${decoded.children.first.age}, ${decoded.children.first.children.length} child)',
  );
}

// 以下是可以通过 binary_serializable_generator 自动生成的代码

class PersonType extends BinaryType<Person> {
  const PersonType();

  @override
  void encodeInto(Person input, BytesBuilder builder) {
    // 将字符串编码为 UTF-8 字节
    utf8String.encodeInto(input.name, builder);
    // 将整数编码为单字节
    uint8.encodeInto(input.age, builder);
    // 将列表编码为长度前缀列表
    const LengthPrefixedListType(uint8, PersonType())
        .encodeInto(input.children, builder);
  }

  @override
  BinaryConversion<Person> startConversion(void Function(Person p1) onValue) =>
      PersonConversion(onValue);
}

class PersonConversion extends CompositeBinaryConversion<Person> {
  PersonConversion(super.onValue);

  @override
  BinaryConversion startConversion() {
    // 开始处理字符串
    return utf8String.startConversion((name) {
      // 处理整数
      currentConversion = uint8.startConversion((age) {
        // 处理列表
        currentConversion = const LengthPrefixedListType(uint8, PersonType())
            .startConversion((children) {
          // 完成对象构造
          onValue(Person(name: name, age: age, children: children));
        });
      });
    });
  }
}

代码解释

  1. Person 类定义

    class Person {
      final String name;
      final int age;
      final List<Person> children;
    
      Person({required this.name, required this.age, required this.children});
    }
    

    这里定义了一个 Person 类,其中包含了名字、年龄和子节点信息。

  2. 创建示例对象

    final sample = Person(
      name: 'Alice',
      age: 87,
      children: [
        Person(
          name: 'Bob',
          age: 49,
          children: [
            Person(
              name: 'Tina',
              age: 17,
              children: [],
            ),
          ],
        ),
        Person(
          name: 'Joe',
          age: 49,
          children: [],
        ),
      ],
    );
    

    创建一个嵌套的 Person 对象实例。

  3. 序列化对象

    final encoded = PersonType().encode(sample);
    

    使用 PersonTypeencode 方法将 Person 对象编码为二进制数据。

  4. 打印编码后的数据

    print(
      'Encoded data: ${encoded.map((b) => b.toRadixString(16).padLeft(2, '0')).join(' ')}',
    );
    

    将编码后的二进制数据以十六进制格式打印出来。

  5. 反序列化二进制数据

    final decoded = PersonType().decode(encoded);
    

    使用 PersonTypedecode 方法将二进制数据解码为 Person 对象。

  6. 打印解码后的数据

    print(
      '1st child of decoded sample: ${decoded.children.first.name} (${decoded.children.first.age}, ${decoded.children.first.children.length} child)',
    );
    

更多关于Flutter数据序列化插件binary_serializable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据序列化插件binary_serializable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用binary_serializable插件进行数据序列化的示例。binary_serializable是一个用于在Flutter中高效地进行二进制数据序列化和反序列化的插件。它依赖于built_valuefixnum等库。

首先,确保你已经在pubspec.yaml文件中添加了binary_serializable及其依赖项:

dependencies:
  flutter:
    sdk: flutter
  binary_serializable: ^x.y.z  # 请替换为最新版本号
  built_value: ^x.y.z  # 请替换为与binary_serializable兼容的版本号
  fixnum: ^x.y.z  # 请替换为最新版本号

dev_dependencies:
  build_runner: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来安装这些依赖项。

接下来,我们创建一个简单的数据模型并使用binary_serializable进行序列化。

  1. 创建一个数据模型类,并使用@BuiltValue@BinarySerializable注解:
import 'package:binary_serializable/binary_serializable.dart';
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:fixnum/fixnum.dart';

part 'model.g.dart';

abstract class MyData implements Built<MyData, MyDataBuilder>, BinarySerializable {
  int get id;
  String get name;
  Int64 get timestamp;

  MyData._();

  factory MyData([updates(MyDataBuilder b)]) = _$MyData;

  static Serializer<MyData> get serializer => _$myDataSerializer;
}

注意:上面的代码使用part 'model.g.dart';来引入自动生成的文件。这个文件将在后续步骤中通过build_runner生成。

  1. 使用build_runner生成必要的序列化代码:

在项目根目录下运行以下命令:

flutter pub run build_runner build

这将生成model.g.dart文件,其中包含序列化和反序列化所需的代码。

  1. 编写序列化和反序列化的示例代码:
import 'dart:typed_data';
import 'package:binary_serializable/binary_serializable.dart';
import 'model.dart'; // 引入之前定义的数据模型

void main() {
  // 创建一个数据对象
  var data = MyData((b) => b
    ..id = 1
    ..name = 'Example'
    ..timestamp = Int64(DateTime.now().millisecondsSinceEpoch));

  // 序列化数据对象
  var buffer = Uint8List(data.sizeInBytes);
  data.writeToBuffer(buffer);

  // 输出序列化后的字节数据(可选)
  print('Serialized data: $buffer');

  // 反序列化数据对象
  var deserializedData = MyData.fromBuffer(buffer);

  // 输出反序列化后的数据对象(可选)
  print('Deserialized data: ${deserializedData.id}, ${deserializedData.name}, ${deserializedData.timestamp}');
}

在这个示例中,我们首先创建了一个MyData对象,然后将其序列化为一个Uint8List。之后,我们从这个字节列表中反序列化回一个MyData对象,并打印出结果。

请确保你正确运行了flutter pub run build_runner build命令,以生成必要的序列化代码,否则你会在编译时遇到找不到_$myDataSerializer等生成的类的错误。

这个示例展示了如何在Flutter项目中使用binary_serializable进行数据序列化和反序列化。根据你的实际需求,你可以扩展数据模型类,并添加更多的字段。

回到顶部