byte[] datas
从byte[]解析数据。
- 读取表数据总行数
datas[length-4,] 末尾4字节:表示数据行数:4*8=32(4G)
1 2
| // 通过数据行数判断所有行数据结束位置 uint total = (uint)(data[data.Length-4]) << 24 | (uint)(data[data.Length-3]) << 16 | (uint)(data[data.Length-2]) << 8 | (uint)(data[data.Length-1]);
|
- 读取单行数据
2.1 读取单行数据总长度
数据部分前3byte,最大:3*8=24(16M)
1 2 3
| // 用于判断单行数据部分结束位置,并移动当前读取位置索引 l = (dAtA[idx] << 16) | (dAtA[idx + 1] << 8) | (dAtA[idx + 2]); idx += 3;
|
2.2 解析单行数据
已知开始索引、长度,通过while读取bytes。
2.2.1 解析单个字段
读取字段信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| // val: 字段类型值,返回值<0:表示非法值 public static int decodeVarVal(byte[] dAtA, ref int iNdEx, ref ulong Val, int l) { for (int shift = 0; ; shift += 7) { if (shift >= 64) { return -1; } if (iNdEx >= l) { return -2; } byte b = dAtA[iNdEx]; iNdEx++; Val |= ((ulong)b & 0x7F) << shift; if (b < 0x80) { break; } } return 0; }
|
低3bit:字段类型,最大:7种
其余:字段号,最大:3*8=24(16M)
1 2 3 4 5 6 7 8 9 10
| PbFunc.decodeVarVal(dAtA, ref iNdEx, ref wire, l);
// 字段号,即列号 int fieldNum = (int)(wire >> 3);
// 值类型,0:基础类型(可直接读取数据) 2:复合类型(先读数据长度再读数据) // 举例: // 0: uint int long 也可以表示只有单个元素的list<int>等 // 2: string list<int> list<string>等 int wireType = (int)(wire & 0x7);
|
案例
excel:
| A |
B |
C |
D |
E |
F |
G |
H |
I |
| Id(key.uint32)* |
StartTime(time) |
EndTime(time) |
Commnet(string) |
SeasonBg(string) |
SeasonTxt(string) |
GachaEntrace(array.uint32) |
ShopImgs(array.string) |
EventImgs(array.string) |
| All |
Client |
Client |
None |
Client |
Client |
Client |
Client |
Client |
| 编号 |
开始时间 |
结束时间 |
备注 |
背景图 |
文字 |
入口展示 |
入口图 |
活动入口图 |
| 1 |
2026-01-15 00:00:00 |
2026-01-22 23:59:59 |
|
ui_banner_bp_ss9 |
|
2|1 |
ui_banner_act_260116_1 |
ui_banner_shop_260116_1 |
| 2 |
2026-01-23 00:00:00 |
2026-01-29 23:59:59 |
|
ui_banner_bp_ss9 |
|
3|2|1 |
ui_banner_act_260116_1 |
ui_banner_act_260123_1 |
bytes:
1 2 3 4 5 6 7 8 9 10 11 12
| 0000 5508 0110 80fb 9ecb 0618 ff92 c9cb 062a 1075 695f 6261 6e6e 6572 5f62 705f 7373 393a 0202 0142 1675 695f 6261 6e6e 6572 5f61 6374 5f32 3630 3131 365f 314a 1775 695f 6261 6e6e 6572 5f73 686f 705f 3236 3031 3136 5f31 0000 5508 0210 8093 c9cb 0618 ff87 eecb 062a 1075 695f 6261 6e6e 6572 5f62 705f 7373 393a 0303 0201 4216 7569 5f62 616e 6e65 725f 6163 745f 3236 3031 3136 5f31 4a16 7569 5f62 616e 6e65 725f 6163 745f 3236 3031 3233 5f31 0000 0002
|
- 数据总行数
- 单行数据
不同行数据的长度是可变的!
2.1 第1行
1 2 3 4 5 6 7 8 9 10
| // 数据长度:01010101=85字节 0000 55
// 数据部分 08 0110 80fb 9ecb 0618 ff92 c9cb 062a 1075 695f 6261 6e6e 6572 5f62 705f 7373 393a 0202 0142 1675 695f 6261 6e6e 6572 5f61 6374 5f32 3630 3131 365f 314a 1775 695f 6261 6e6e 6572 5f73 686f 705f 3236 3031 3136 5f31
|
2.2 第2行
1 2 3 4 5 6 7 8 9 10
| // 数据长度:01010101=85字节 0000 55
// 数据部分 08 0210 8093 c9cb 0618 ff87 eecb 062a 1075 695f 6261 6e6e 6572 5f62 705f 7373 393a 0303 0201 4216 7569 5f62 616e 6e65 725f 6163 745f 3236 3031 3136 5f31 4a16 7569 5f62 616e 6e65 725f 6163 745f 3236 3031 3233 5f31
|
- 字段数据
以第一行为例。
1 2 3 4 5 6
| 08 0110 80fb 9ecb 0618 ff92 c9cb 062a 1075 695f 6261 6e6e 6572 5f62 705f 7373 393a 0202 0142 1675 695f 6261 6e6e 6572 5f61 6374 5f32 3630 3131 365f 314a 1775 695f 6261 6e6e 6572 5f73 686f 705f 3236 3031 3136 5f31
|
第1个字段:Id(key.uint32)*
1 2 3 4
| // 0000 1000,1:列号(其余bit),0(后3bit):基本类型 08 // 字段值,基础类型直接读取 01
|
第2个字段:StartTime(time)
1 2 3 4
| // 0001 0000,2:列号,0(后3bit):基本类型 10 // 字段值,基础类型直接读取 80fb 9ecb 06
|
第3个字段:EndTime(time)
1 2 3 4
| // 0001 1000,3:列号,0(后3bit):基本类型 18 // 字段值,基础类型直接读取 ff92 c9cb 06
|
第5个字段:SeasonBg(string)(第4个是注释跳过)
1 2 3 4 5
| // 0010 1010,5:列号,2(后3bit): 引用类型 2a // 字段值,引用类型先读取长度16(0001 0000),再读取值 10 75 695f 6261 6e6e 6572 5f62 705f 7373 39
|
第6个字段:SeasonTxt(string)
第7个字段:GachaEntrace(array.uint32)
1 2 3 4 5
| // 0011 1010,7:列号,2(后3bit): 引用类型 3a // 字段值,引用类型先读取长度2(0000 0010),再读取值 02 02 01
|
第8个字段:ShopImgs(array.string)
1 2 3 4 5
| // 1000 0010,8:列号,2(后3bit): 引用类型 42 // 字段值,引用类型先读取长度22(0001 0110),再读取值 16 75 695f 6261 6e6e 6572 5f61 6374 5f32 3630 3131 365f 31
|
第9个字段:EventImgs(array.string)
1 2 3 4 5
| // 1000 1010,9:列号,2(后3bit): 引用类型 4a // 字段值,引用类型先读取长度23(0001 0111),再读取值 17 75 695f 6261 6e6e 6572 5f73 686f 705f 3236 3031 3136 5f31
|