我序列化每個玩家服務器端的數據,大小約爲128kb。我序列化一個必須映射的[255,255] bools數組,我可以使用什麼替代方法,因爲我聽說gzip實際上會增加大小?序列化數據太大
我聽說過protobuf-net,但它沒有記錄,也沒有例子存在於互聯網上。
我序列化每個玩家服務器端的數據,大小約爲128kb。我序列化一個必須映射的[255,255] bools數組,我可以使用什麼替代方法,因爲我聽說gzip實際上會增加大小?序列化數據太大
我聽說過protobuf-net,但它沒有記錄,也沒有例子存在於互聯網上。
如果您將布爾值表示爲位並將其序列化爲二進制文件,那只有大約8千字節。
如果你需要的是文本,使用base64序列化二進制文件,這將使其大約12千字節。
將二維數組展平爲一維數組,並從中創建一個BitArray
。
例子:
bool[] bools = { true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true };
BitArray bits = new BitArray(bools);
byte[] bytes = new byte[3];
bits.CopyTo(bytes, 0);
Console.WriteLine(BitConverter.ToString(bytes));
Console.WriteLine(Convert.ToBase64String(bytes));
Outut:
FF-FF-0F
//8P
您可以使用(一維)BitArray進行序列化。這將這些比特打包成字節。
我會做會的第一件事:不是數據存儲在bool[,]
- 這是非常低效的,和一個真正的痛苦來存儲。我會寫它墊片以平坦byte[]
的包裝:
public sealed class BitGrid
{
public BitGrid() {
// 255 * 255 = 32 bytes per row, 255 rows
bytes = new byte[8160];
}
public BitGrid(byte[] data)
{
if (data == null) throw new ArgumentNullException("data");
if (data.Length != 8160) throw new ArgumentException("data");
this.bytes = data;
}
readonly byte[] bytes;
public bool this[byte x, byte y]
{
get
{
int xByte = x/8, xBit = x % 8;
byte val = bytes[(32 * y) + xByte];
switch (xBit)
{
case 0: return (val & 1) != 0;
case 1: return (val & 2) != 0;
case 2: return (val & 4) != 0;
case 3: return (val & 8) != 0;
case 4: return (val & 16) != 0;
case 5: return (val & 32) != 0;
case 6: return (val & 64) != 0;
case 7: return (val & 128) != 0;
}
throw new InvalidOperationException("oops!");
}
set
{
int xByte = x/8, xBit = x % 8;
int offset = (32 * y) + xByte;
byte val = bytes[offset];
if (value)
{
switch (xBit)
{
case 0: val |= 1; break;
case 1: val |= 2; break;
case 2: val |= 4; break;
case 3: val |= 8; break;
case 4: val |= 16; break;
case 5: val |= 32; break;
case 6: val |= 64; break;
case 7: val |= 128; break;
}
}
else
{
switch (xBit)
{
case 0: val &= 254; break;
case 1: val &= 253; break;
case 2: val &= 251; break;
case 3: val &= 247; break;
case 4: val &= 239; break;
case 5: val &= 223; break;
case 6: val &= 191; break;
case 7: val &= 127; break;
}
}
bytes[offset] = val;
}
}
public byte[] ToArray()
{
return (byte[])bytes.Clone();
}
}
然後序列化,它只是:
byte[] data = grid.ToArray();
// store "data"
和反序列化,它只是:
byte[] data = ...
grid = new BitGrid(data);
您可以使用File.ReadAllBytes
/File.WriteAllBytes
方法將byte[]
保存/加載到磁盤或從磁盤加載,或者如果您有其他數據要存儲,則任何標準串行器將會w ork與byte[]
罰款。該數據將始終爲8160字節 - 略低於8K。
不,GZipStream不會增加這個大小。你通過實際嘗試來抵抗FUD。 –
@Hans很好,它*可以*,這取決於數據看起來如何隨機。假設一個很好的實現*斑點*數據是隨機的,你仍然有一個幀頭的開銷。一個不好的實現(沒有發現它是隨機的)可以做任何事情。 –
你只是增加了更多的FUD,它仍然不會讓他嘗試它。 –