You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Dart对象实例与字节互转以通过TCP传输?

在Dart中实现对象的二进制序列化(类似Java Serializable)

Dart没有内置的Serializable接口,但可以通过以下几种方式实现对象与字节的互转,满足你TCP Socket传输的需求:

方案1:手动实现序列化/反序列化(无依赖)

适合结构简单的类,完全自定义字节格式,无需额外库。

示例代码

首先定义MessageDto类,添加序列化和反序列化方法:

import 'dart:convert';
import 'dart:typed_data';

class MessageDto {
  final String msg;
  final String action;
  final String method;

  MessageDto({required this.msg, required this.action, required this.method});

  // 将对象转为字节列表
  Uint8List toBytes() {
    final msgBytes = utf8.encode(msg);
    final actionBytes = utf8.encode(action);
    final methodBytes = utf8.encode(method);

    // 用4字节存储每个字符串的长度(大端序),再拼接字符串字节
    final buffer = BytesBuilder();
    buffer.add(_int32ToBytes(msgBytes.length));
    buffer.add(msgBytes);
    buffer.add(_int32ToBytes(actionBytes.length));
    buffer.add(actionBytes);
    buffer.add(_int32ToBytes(methodBytes.length));
    buffer.add(methodBytes);

    return buffer.toBytes();
  }

  // 从字节列表重建对象
  factory MessageDto.fromBytes(Uint8List bytes) {
    final reader = ByteData.view(bytes.buffer);
    int offset = 0;

    // 读取msg字段
    final msgLength = reader.getInt32(offset, Endian.big);
    offset += 4;
    final msg = utf8.decode(bytes.sublist(offset, offset + msgLength));
    offset += msgLength;

    // 读取action字段
    final actionLength = reader.getInt32(offset, Endian.big);
    offset += 4;
    final action = utf8.decode(bytes.sublist(offset, offset + actionLength));
    offset += actionLength;

    // 读取method字段
    final methodLength = reader.getInt32(offset, Endian.big);
    offset += 4;
    final method = utf8.decode(bytes.sublist(offset, offset + methodLength));

    return MessageDto(msg: msg, action: action, method: method);
  }

  // 辅助方法:将int32转为大端序字节
  Uint8List _int32ToBytes(int value) {
    final byteData = ByteData(4);
    byteData.setInt32(0, value, Endian.big);
    return byteData.buffer.asUint8List();
  }
}

使用方式

void main(List<String> arguments) async {
  MessageDto messageDto = MessageDto(
    msg: 'essa é a menssagem',
    action: 'action',
    method: 'method',
  );

  // 对象转字节
  Uint8List buffer = messageDto.toBytes();
  send(buffer); // 替换为你的TCP发送逻辑

  // 服务端接收后重建对象
  MessageDto received = MessageDto.fromBytes(buffer);
  print(received.msg); // 输出: essa é a menssagem
}

方案2:使用Protobuf(适合跨语言场景)

Protobuf是Google的二进制序列化协议,支持多语言,生成的代码高效且维护方便。

步骤

  1. 安装依赖:

    dart pub add protobuf
    dart pub global activate protoc_plugin
    

    确保protoc编译器和protoc_plugin的bin目录在系统PATH中。

  2. 定义.proto文件(message.proto):

    syntax = "proto3";
    
    message MessageDto {
      string msg = 1;
      string action = 2;
      string method = 3;
    }
    
  3. 生成Dart代码:

    protoc --dart_out=./lib ./message.proto
    
  4. 使用生成的类:

    import 'package:protobuf/protobuf.dart';
    import 'message.pb.dart'; // 生成的Dart文件
    
    void main() {
      final messageDto = MessageDto()
        ..msg = 'essa é a menssagem'
        ..action = 'action'
        ..method = 'method';
    
      // 对象转字节
      Uint8List buffer = messageDto.writeToBuffer();
      send(buffer);
    
      // 服务端重建对象
      final received = MessageDto.fromBuffer(buffer);
      print(received.msg);
    }
    

方案3:使用built_value(适合复杂对象)

built_value是Dart的序列化库,支持二进制序列化,同时提供不可变对象、哈希等特性。

步骤

  1. 添加依赖(pubspec.yaml):

    dependencies:
      built_value: ^8.6.1
      built_collection: ^5.1.1
    
    dev_dependencies:
      build_runner: ^2.4.4
      built_value_generator: ^8.6.1
    
  2. 定义MessageDto类(message_dto.dart):

    import 'package:built_value/built_value.dart';
    import 'package:built_value/serializer.dart';
    import 'package:built_value/builder.dart';
    
    part 'message_dto.g.dart';
    
    abstract class MessageDto implements Built<MessageDto, MessageDtoBuilder> {
      String get msg;
      String get action;
      String get method;
    
      MessageDto._();
      factory MessageDto([void Function(MessageDtoBuilder) updates]) = _$MessageDto;
    
      // 对象转字节
      Uint8List toBytes() {
        return serializers.serializeWith(MessageDto.serializer, this) as Uint8List;
      }
    
      // 字节转对象
      static MessageDto fromBytes(Uint8List bytes) {
        return serializers.deserializeWith(MessageDto.serializer, bytes)!;
      }
    
      static Serializer<MessageDto> get serializer => _$messageDtoSerializer;
    }
    
    // 配置序列化器
    Serializers serializers = (_$serializers.toBuilder()
          ..addBuilderFactory(
            const FullType(MessageDto),
            () => MessageDtoBuilder(),
          ))
        .build();
    
  3. 生成代码:

    dart run build_runner build
    
  4. 使用方式:

    void main() {
      final messageDto = MessageDto((b) => b
        ..msg = 'essa é a menssagem'
        ..action = 'action'
        ..method = 'method');
    
      Uint8List buffer = messageDto.toBytes();
      send(buffer);
    
      final received = MessageDto.fromBytes(buffer);
      print(received.msg);
    }
    

内容的提问来源于stack exchange,提问作者user2859203

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 11:50:00