LiteByte教程
简介

LiteByte是一种轻量级的二进制数据交换格式。
体积小巧、简单易用是设计目标。主要用于解决前后台数据传输量的问题。
作者:冰封百度(ZhangYu)
设计的灵感来源于C# struct内存对齐后的紧凑格式。暂时只实现了C#版本。
特点
1.紧凑的二进制数据格式,支持变长整型,数据量小。
2.用近似代码定义类的方式定义对象结构,使用方便。
实现思路
把一个对象分为两个部分:结构和值。
结构用配置文件定义,越方便越好。
值用于网络传输,越小越好。
前后台依赖相同的结构配置文件,转换时把对象的值拆出来传输,解析时把值还原成对象。
使用方法
1.创建自定义结构文件CustomType.lbs (LiteByte Schema 文本文件)。
2.定义对象字段(像写类一样写结构、类型和名称)。
3.调用LBUtil.Serialize(object) 把对象序列化成二进制数据。
4.调用LBUtil.Deserilize(bytes) 把二进制数据反序列化成对象。
代码样例:
// 自定义对象结构:
// 写结构配置和C#中写struct一样, 访问修饰符可以不写,读配置文件的时候会被忽略 /// <summary> 玩家信息测试 | PlayerInfo test </summary>
public struct PlayerInfo { public uint id;
public string nickname;
public byte gender;
public bool isVip;
public int lv;
public int hp;
public int mp;
public int exp; } // 命名空间
using LiteByte; // 创建对象
PlayerInfo player = new PlayerInfo();
player.id = ;
player.nickname = "冰封百度";
player.gender = ;
player.isVip = true;
player.lv = ;
player.hp = ;
player.mp = ;
player.exp = ; // 序列化:
string typeName = "PlayerInfo";
byte[] bytes = LBUtil.Serialize(typeName, player); // 长度:31字节 // 反序列化:
PlayerInfo info = LBUtil.Deserialize<PlayerInfo>(typeName, bytes);
转换结果:

代码说明:
1.序列化对象时用LBUtil.Serialize("name", obj)
2.反序列化对象时候用LBUtil.Deserilize("name", obj)
3.可以转换自定义的struct和class 字段需要是public的
4.提供了通用的转换对象LBObject,可以Set和Get值,用于动态创建全新的自定义结构。由于序列化和反序列化自定义struct和class时用了反射,效率不高,用LBObject转换效率会更高一些,但用起来会麻烦一些,按自己喜欢的方式使用就好。
支持的数据类型
数据类型介绍
1.基本的值类型:bool、byte、short、int、long
2.字符串 string (支持UTF8、Unicode、ASCII三种编码方式)
3.数组 (类型+"[]"会被识别成数组)
4.自定义类型 (复杂对象)
基本数据类型
比特型(7种)
| 类型 | 长度 | 值范围 |
| Bit1(Boolean) | 1位 | 0 ~ 1 |
| Bit2(Byte) | 2位 | 0 ~ 3 |
| Bit3(Byte) | 3位 | 0 ~ 7 |
| Bit4(Byte) | 4位 | 0 ~ 15 |
| Bit5(Byte) | 5位 | 0 ~ 31 |
| Bit6(Byte) | 6位 | 0 ~ 63 |
| Bit7(Byte) | 7位 | 0 ~ 127 |
整型(16种)
| 类型 | 长度 | 值范围 |
| Int8(sbyte) | 1字节 | -128 ~ 127 |
| Int16(short) | 2字节 | -32768 ~ -32767 |
| Int24(int) | 3字节 | -8388608 ~ 8388607 |
| Int32(int) | 4字节 | -2147483648 ~ 2147483647 |
| Int40(long) | 5字节 | -549755813888 ~ 549755813887 |
| Int40(long) | 6字节 | -140737488355328 ~ 140737488355327 |
| Int40(long) | 7字节 | -36028797018963968 ~ 36028797018963967 |
| Int64(long) | 8字节 | -9223372036854775808 ~ 9223372036854775807 |
| UInt8(byte) | 1字节 | 0 ~ 255 |
| UInt16(ushort) | 1字节 | 0 ~ 65535 |
| UInt24(uint) | 1字节 | 0 ~ 16777215 |
| UInt32(uint) | 1字节 | 0 ~ 4294967295 |
| UInt40(ulong) | 1字节 | 0 ~ 1099511627775 |
| UInt48(ulong) | 1字节 | 0 ~ 281474976710655 |
| UInt56(ulong) | 1字节 | 0 ~ 72057594037927935 |
| UInt64(ulong) | 1字节 | 0 ~ 18446744073709551615 |
浮点型(5种)
| 类型 | 长度 | 有效数字 | 值范围 |
| Float8(float) | 1字节 | 7位 | 0/255 ~ 255/255 |
| Float16(float) | 2字节 | 3位 | ±6.55E +4 |
| Float24(float) | 3字节 | 5位 | ±1.8447E +19 |
| Float32(float) | 4字节 | 7位 | ±3.402823E +38 |
| Float64(double) | 8字节 | 15位 | ±1.7976931348623157E +308 |
变长整型(7种)
| 类型 | 长度 | 值范围 |
| VarInt16(short) | 1位 + 1~2字节 | 同Int16 |
| VarInt32(int) | 2位 + 1~4字节 | 同Int32 |
| VarInt64(long) | 3位 + 1~8字节 | 同Int64 |
| VarUInt16(ushort) | 1位 + 1~2字节 | 同UInt16 |
| VarUInt32(uint) | 2位 + 1~4字节 | 同UInt32 |
| VarUInt64(ulong) | 3位 + 1~8字节 | 同UInt64 |
| VarLength(int) | 3位 + 1~8字节 | -1 ~ (Int32.MaxValue/2 - 1) |
字符串(3种编码)
| 类型 | 单个字符长度 | 总长度范围 |
| UTF8(string) | 1~4字节 | 头(1~4)字节+体(0 ~ 1073741822)字节 |
| Unicode(string) | 2字节 | 头(1~4)字节+体(0 ~ 1073741822)x2字节 |
| ASCII(string) | 1字节 | 头(1~4)字节+体(0 ~ 1073741822)字节 |
复杂数据类型(2种)
| 类型 | 表达式 |
| 数组(Array) | 类型名称[] |
| 字典(未实现) | Dictionary<基本类型, 类型名称> |
| 自定义类型 | 只要不和基本类型和数组重名 即被当作自定义类型 |
自定义类型结构配置(LiteByte Schema)样例
以下样例中 基本类型默认应用以下简称配置
Bit1 = bool
Int8 = sbyte
UInt8 = byte
VarInt32 = int
VarUnt32 = uint
VarInt64 = long
VarUInt64 = ulong
UTF8 = string
基本数据类型 结构:
struct BaseTypeST {
// 比特型
bool boolValue;
// 有符号整型
sbyte sbyteValue;
short shortValue;
int intValue;
long longValue;
// 无符号整型
byte byteValue;
ushort ushortValue;
uint uintValue;
ulong ulongValue;
// 有符号浮点型
float floatValue;
double doubleValue;
// 字符型(UTF8)
string stringValue;
}
数组 结构:
struct ArrayST {
int[] ids;
string[] names;
}
用户信息 结构:
struct UserInfoST {
uint id;
string username;
string nickname;
int hp;
int mp;
long exp;
long gold;
byte age;
bool isVip;
}
各语言类型对照表
| 类型 | 长度 | C# | Java | C++ | Go |
| Bit1 | 1位 | bool | boolean | char | bool |
| Bit2 | 2位 | byte | byte | char | uint8 |
| Bit3 | 3位 | byte | byte | char | uint8 |
| Bit4 | 4位 | byte | byte | char | uint8 |
| Bit5 | 5位 | byte | byte | char | uint8 |
| Bit6 | 6位 | byte | byte | char | uint8 |
| Bit7 | 7位 | byte | byte | char | uint8 |
| Int8 | 1字节 | sbyte | sbyte | char | int8 |
| Int16 | 2字节 | short | short | short | int16 |
| Int24 | 3字节 | int | int | int | int32 |
| Int32 | 4字节 | int | int | int | int32 |
| Int40 | 5字节 | long | long | long long | int64 |
| Int48 | 6字节 | long | long | long long | int64 |
| Int56 | 7字节 | long | long | long long | int64 |
| Int64 | 8字节 | long | long | long long | int64 |
| UInt8 | 1字节 | byte | byte | unsigned char | uint8 |
| UInt16 | 2字节 | ushort | ushort | unsigned short | uint16 |
| UInt24 | 3字节 | uint | uint | unsigned int | uint32 |
| UInt32 | 4字节 | uint | uint | unsigned int | uint32 |
| UInt40 | 5字节 | ulong | ulong | unsigned long long | uint64 |
| UInt48 | 6字节 | ulong | ulong | unsigned long long | uint64 |
| UInt56 | 7字节 | ulong | ulong | unsigned long long | uint64 |
| UInt64 | 8字节 | ulong | ulong | unsigned long long | uint64 |
| Float8 | 1字节 | float | float | float | float32 |
| Float16 | 2字节 | float | float | float | float32 |
| Float24 | 3字节 | float | float | float | float32 |
| Float32 | 4字节 | float | float | float | float32 |
| Float64 | 8字节 | double | double | double | float64 |
| VarInt16 | 1位+1~2字节 | short | short | short | int16 |
| VarInt32 | 2位+1~4字节 | int | int | int | int32 |
| VarInt64 | 3位+1~8字节 | long | long | long long | int64 |
| VarUInt16 | 1位+1~2字节 | ushort | ushort | unsigned short | uint16 |
| VarUInt32 | 2位+1~4字节 | uint | uint | unsigned int | uint32 |
| VarUInt64 | 3位+1~8字节 | ulong | ulong | unsigned long long | uint64 |
| VarLength | 2位+1~4字节 | int | int | int | int32 |
| UTF8 | 1~4字节 | string | string | string | string |
| Unicode | 2字节 | string | string | string | string |
| ASCII | 1字节 | string | string | string | string |
共计38种
数据类型说明:
1.对bool型的支持最好,一个bool型只占1位(1/8个字节)。
2.支持变长整数(short、int、long、ushort、uint、ulong)
3.支持null值 (能空的类型string, array, object,都支持它们为空的情况)
4.建议在定义数据格式时,用尽量小的类型定义字段,这样序列化的数据体积会更小,如果懒得写,可以考虑使用变长数据。
5.支持自定义数据类型名称,因为相同的数据类型在不同的编程语言中名字不一样,为了方便使用,我添加了一套内置数据类型名称并添加了一个类型名称映射的功能,可以自定义基本值类型的名称,按照自己喜欢的风格命名就好。
6.因为在编写变长数据类型的过程中用到了一些不常见的数据格式,为了重用类型,索性就一起支持了,在对数据大小很严格的环境会有帮助,这些非常规的数据类型有:
Bit2~Bit7 占2~7位
Int24、Int40、Int48、Int56 占3、5、6、7字节
UInt24、UInt40、UInt48、UInt56 占3、5、6、7字节
VarLength 用于表示string和array的长度 值范围-1~(int.MaxValue/2 - 1)
其他说明:
由于能力有限,暂时只实现了C#版本(在Unity中实现的,算半个.Net吧)
其他语言后续有时间再写,虽然造了个轮子 不过感觉造轮子的过程中收获远大于付出,挺开心的。
建了个群,有需求的可加。
QQ群:715800513
项目GitHub:https://github.com/zhangyukof/litebyte
测试Demo:
链接:https://pan.baidu.com/s/1yQVn6f4YAkNBDnD0g86xow
提取码:lio4
转载请标明原文地址:https://www.cnblogs.com/zhangyukof/p/12073041.html
LiteByte教程的更多相关文章
- Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...
- Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数
上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...
- Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数
上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...
- Angular2入门系列教程4-服务
上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...
- Angular2入门系列教程1-使用Angular-cli搭建Angular2开发环境
一直在学Angular2,百忙之中抽点时间来写个简单的教程. 2016年是前端飞速发展的一年,前端越来越形成了(web component)组件化的编程模式:以前Jquery通吃一切的田园时代一去不复 ...
- wepack+sass+vue 入门教程(三)
十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...
- wepack+sass+vue 入门教程(二)
六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...
- wepack+sass+vue 入门教程(一)
一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...
- Virtual Box配置CentOS7网络(图文教程)
之前很多次安装CentOS7虚拟机,每次配置网络在网上找教程,今天总结一下,全图文配置,方便以后查看. Virtual Box可选的网络接入方式包括: NAT 网络地址转换模式(NAT,Network ...
随机推荐
- 【目标检测实战】目标检测实战之一--手把手教你LMDB格式数据集制作!
文章目录 1 目标检测简介 2 lmdb数据制作 2.1 VOC数据制作 2.2 lmdb文件生成 lmdb格式的数据是在使用caffe进行目标检测或分类时,使用的一种数据格式.这里我主要以目标检测为 ...
- NIO流的学习以及Buffer的相关操作
NIO的使用 一).什么叫NIO? 定义:是一套新的Java I/O标准, 在java1.4中被纳入JDK中. 二).NIO的实现方法 NIO是基于块的, 以块为基本单位处理数据. 标准的I/O是基于 ...
- 深入理解跳表在Redis中的应用
本文首发于:深入理解跳表在Redis中的应用微信公众号:后端技术指南针持续输出干货 欢迎关注 前面写了一篇关于跳表基本原理和特性的文章,本次继续介绍跳表的概率平衡和工程实现, 跳表在Redis.Lev ...
- java集合讲解
java集合讲解 1.概述 集合类的顶级接口是Iterable,Collection继承了Iterable接口 常用的集合主要有 3 类,Set,List,Queue,他们都是接口,都继于Collec ...
- mvc 学习笔记
1.routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); MVC中的路由忽略,只要访问的地址中带有 .axd , 该请求都将排除在mv ...
- [ch03-02] 交叉熵损失函数
系列博客,原文在笔者所维护的github上:https://aka.ms/beginnerAI, 点击star加星不要吝啬,星越多笔者越努力. 3.2 交叉熵损失函数 交叉熵(Cross Entrop ...
- ExtentTestNGIReporterListener
package com.testng.config; import com.aventstack.extentreports.ExtentReports; import com.aventstack. ...
- Android利用碎片fragment实现底部标题栏(Github模板开源)
在安卓开发当中,一个十分重要的布局则是底部标题栏了,拥有了底部标题栏,我们就拥有了整个软件UI开发的框架,一般而言,整个软件的布局首先就是从底部标题栏开始构建,然后再开始其他模块的编写,组成一个完善的 ...
- Python-TCP客户端程序开发
TCP客户端,需要与服务端建立连接,连接建立成功后才可以进行数据的传输. # 1.导入模块 import socket if __name__ == '__main__': # 2.创建套接字对象 t ...
- 简单易懂的ftp脚本自动登录教程
我在上上篇<nmon脚本--对Linux服务器的监控>的脚本中,使用了ftp的自动登录.结果有人询问,遂决定专门写一篇简单易懂的博客,来说明如何解决ftp的自动登录问题. 一.Window ...