/// <summary> /// 序列化一个对象到Byte数组,无法序列化,将抛出ArgumentException异常 /// </summary> /// <param name="obj">对象</param> /// <param name="writeToBytes">将要在这个数组基础上开始写入,指定Null表示新建一个数组</param> /// <param name="startIndex">将要从数组的哪个位置开始写入</param> /// <param name="maxWriteSize">最大允许的写入长度</param> /// <param name="fullLengthSchema">是否完整包含每个子对象的长度</param> /// <returns>返回有效大小</returns> public static int SerializeTo(object obj, ref byte[] writeToBytes, int startIndex, int maxWriteSize, bool fullLengthSchema = true) { //try { bool isFieldNullable = false; //数据块 ZipBytesWriter bwData; if (writeToBytes != null) { bwData = new ZipBytesWriter(writeToBytes, startIndex, maxWriteSize); } else { bwData = new ZipBytesWriter(maxWriteSize); } //写标识头 bwData.Write((fullLengthSchema) ? Byte_One : Byte_Zero); if (obj == null) { if (fullLengthSchema) { bwData.Write((ushort)1); } bwData.Write(Byte_Zero); writeToBytes = bwData.Bytes; return(bwData.EffectiveBytesLength); } int metablockStart = 0; int metablockLen = 0; Stack <SerializeInfo> bufStack = new Stack <SerializeInfo>(); bufStack.Push(new SerializeInfo(obj, isFieldNullable, bwData.EffectiveBytesLength)); if (fullLengthSchema) { bwData.Write(DefaultFieldLen); } while (bufStack.Count > 0) { SerializeInfo nowSerializeInfo = bufStack.Peek(); if (nowSerializeInfo.TheObject == null) { bwData.WriteNullHead(true); //写入null bufStack.Pop(); if (fullLengthSchema) { metablockStart = nowSerializeInfo.ByteStartIndexOrEndPoint; metablockLen = bwData.EffectiveBytesLength - metablockStart - 2; ZipBytesWriter.WriteAtUshort(bwData.Bytes, metablockStart, (ushort)metablockLen); } } else { if (nowSerializeInfo.TheType == null) //未检查过 { if (nowSerializeInfo.IsNullable) { bwData.WriteNullHead(false); } nowSerializeInfo.TheType = nowSerializeInfo.TheObject.GetType(); //是基础元素 if (BytesHelper.TryWriteBytes(nowSerializeInfo.TheObject, nowSerializeInfo.TheType, bwData)) { bufStack.Pop(); if (fullLengthSchema) { metablockStart = nowSerializeInfo.ByteStartIndexOrEndPoint; metablockLen = bwData.EffectiveBytesLength - metablockStart - 2; if (metablockLen > ushort.MaxValue) { throw new Exception("序列化的子字段大小超出65535:" + nowSerializeInfo.FieldInfos[nowSerializeInfo.Index - 1].FieldName); } ZipBytesWriter.WriteAtUshort(bwData.Bytes, metablockStart, (ushort)metablockLen); } } else //不是基础元素 { if (nowSerializeInfo.TheType.IsArray) { nowSerializeInfo.IsArray = true; nowSerializeInfo.Length_FieldInfo = (nowSerializeInfo.TheObject as Array).Length; //写入数组长度 bwData.WriteArrayHead(nowSerializeInfo.Length_FieldInfo); } else if (nowSerializeInfo.TheType.GetInterface("IList`1", false) != null) { nowSerializeInfo.IsIList = true; nowSerializeInfo.Length_FieldInfo = (nowSerializeInfo.TheObject as IList).Count; //写入数组长度 bwData.WriteArrayHead(nowSerializeInfo.Length_FieldInfo); } else if (nowSerializeInfo.TheType.GetInterface("IDictionary`2", false) != null) { nowSerializeInfo.IsIDictionary = true; IDictionary id = nowSerializeInfo.TheObject as IDictionary; int dLength = id.Count; nowSerializeInfo.Length_FieldInfo = dLength * 2; object[] kvs = new object[nowSerializeInfo.Length_FieldInfo]; id.Keys.CopyTo(kvs, 0); id.Values.CopyTo(kvs, dLength); nowSerializeInfo.TheObject = kvs; //写入数组长度 bwData.WriteArrayHead(nowSerializeInfo.Length_FieldInfo); } else { bwData.WriteNullHead(false); DynamicFieldInfo[] fis; lock (FI_Lookup) { if (FI_Lookup.ContainsKey(nowSerializeInfo.TheType)) { fis = FI_Lookup[nowSerializeInfo.TheType]; } else { PropertyInfo[] fi = nowSerializeInfo.TheType.GetProperties(AllInstanceBindingFlags).OrderBy(c => c.Name).ToArray(); List <DynamicFieldInfo> tempFis = new List <DynamicFieldInfo>(); for (int i = 0; i < fi.Length; i++) { PropertyInfo fiNow = fi[i]; object[] at = fiNow.GetCustomAttributes(typeof(System.NonSerializedAttribute), true); if (at.Length == 0) { tempFis.Add(new DynamicFieldInfo() { TheField = fiNow }); } } fis = tempFis.ToArray(); FI_Lookup.Add(nowSerializeInfo.TheType, fis); } } nowSerializeInfo.FieldInfos = fis; nowSerializeInfo.Length_FieldInfo = fis.Length; } if (nowSerializeInfo.Length_FieldInfo == 0) //虽然不是基础元素,但没有可序列化的字段 { bufStack.Pop(); if (fullLengthSchema) { metablockStart = nowSerializeInfo.ByteStartIndexOrEndPoint; metablockLen = bwData.EffectiveBytesLength - metablockStart - 2; if (metablockLen > ushort.MaxValue) { throw new Exception("序列化的子字段大小超出65535:" + nowSerializeInfo.FieldInfos[nowSerializeInfo.Index - 1].FieldName); } ZipBytesWriter.WriteAtUshort(bwData.Bytes, metablockStart, (ushort)metablockLen); } } else { nowSerializeInfo.Index = 0; isFieldNullable = false; object innerObject = nowSerializeInfo.GetInnerField(ref isFieldNullable); nowSerializeInfo.Index++; bufStack.Push(new SerializeInfo(innerObject, isFieldNullable, bwData.EffectiveBytesLength)); if (fullLengthSchema) { bwData.Write(DefaultFieldLen); } } } } else //上次检查过 { if (nowSerializeInfo.Length_FieldInfo == nowSerializeInfo.Index) //检查完了 { bufStack.Pop(); if (fullLengthSchema) { metablockStart = nowSerializeInfo.ByteStartIndexOrEndPoint; metablockLen = bwData.EffectiveBytesLength - metablockStart - 2; if (metablockLen > ushort.MaxValue) { throw new Exception("序列化的子字段大小超出65535:" + nowSerializeInfo.FieldInfos[nowSerializeInfo.Index - 1].FieldName); } ZipBytesWriter.WriteAtUshort(bwData.Bytes, metablockStart, (ushort)metablockLen); } } else { isFieldNullable = false; object innerObject = nowSerializeInfo.GetInnerField(ref isFieldNullable); nowSerializeInfo.Index++; bufStack.Push(new SerializeInfo(innerObject, isFieldNullable, bwData.EffectiveBytesLength)); if (fullLengthSchema) { bwData.Write(DefaultFieldLen); } } } } } writeToBytes = bwData.Bytes; return(bwData.EffectiveBytesLength); } //catch (Exception ee) { //throw new SerializeException(obj.GetType().ToString() + "Data bytes and type not match:" + ee.Message); } }
/// <summary> /// 反序列化Byte数组到一个对象,无法反序列化,将抛出ArgumentException异常 /// </summary> /// <param name="objectType">对象类型</param> /// <param name="bytesValue">二进制数据</param> /// <param name="startIndex">开始执行的位置</param> /// <param name="maxReadSize">指定支持最大反序列化的数据大小</param> /// <param name="readLength">实际反序列化时读取的元素个数</param> /// <returns>对象</returns> public static object DeserializeFrom(Type objectType, byte[] bytesValue, int startIndex, int maxReadSize, out int readLength) { try { ZipBytesReader brData = new ZipBytesReader(startIndex, maxReadSize, bytesValue); int point = startIndex; object fatherObject = null; object innerObject = null; int readEnd = 0; byte isNull = 0; int totalLength = 0; int nextSeekTo = 0; ushort metablockLen = 0; //新的字段信息,一般只保存类型和父类 SerializeInfo innerSerializeInfo; Stack <SerializeInfo> bufStack = new Stack <SerializeInfo>(); bool fullLengthSchema = false; if (brData.ReadByte() != Byte_Zero) { fullLengthSchema = true; metablockLen = brData.TryReadMetaBlockLength(); totalLength = brData.Position + metablockLen; } bufStack.Push(new SerializeInfo(objectType, totalLength)); while (bufStack.Count > 0) { //当前的字段信息 SerializeInfo nowSerializeInfo = bufStack.Peek(); readEnd = nowSerializeInfo.ByteStartIndexOrEndPoint; if (nowSerializeInfo.TheObject == null) //未检查过 { //专门处理Nullable类型 if (nowSerializeInfo.TheType.IsGenericType) { if (nowSerializeInfo.TheType.GetGenericTypeDefinition() == SerializeInfo.Type_Nullable) { isNull = brData.ReadByte(); if (isNull == Byte_Zero) //为null { nowSerializeInfo.FatherSerializeInfo.Index++; bufStack.Pop(); if (fullLengthSchema) { if (readEnd >= totalLength) { break; } brData.SeekNextTo(readEnd); } continue; } else { nowSerializeInfo.TheType = nowSerializeInfo.TheType.GetGenericArguments()[0]; } } } //基础类 if (BytesHelper.TryGetValue(nowSerializeInfo.TheType, out innerObject, brData)) { if (nowSerializeInfo.FatherSerializeInfo != null) //有可能直接就是个基础类型 { if (nowSerializeInfo.FatherSerializeInfo.IsIDictionary) { if (nowSerializeInfo.FatherSerializeInfo.Index < nowSerializeInfo.FatherSerializeInfo.Length_FieldInfo / 2) { nowSerializeInfo.FatherSerializeInfo.Keys[nowSerializeInfo.FatherSerializeInfo.Index] = innerObject; } else { nowSerializeInfo.FatherSerializeInfo.SetInnerField(innerObject); } } else { nowSerializeInfo.FatherSerializeInfo.SetInnerField(innerObject); } nowSerializeInfo.FatherSerializeInfo.Index++; } else //有可能直接就是个基础类型 { fatherObject = innerObject; } bufStack.Pop(); if (fullLengthSchema) { if (readEnd >= totalLength) { break; } if (readEnd > brData.Position) { brData.SeekNextTo(readEnd); } } } else //非基础类 { isNull = brData.ReadByte(); if (isNull == Byte_Zero) //为null { if (nowSerializeInfo.FatherSerializeInfo == null) //直接就是null { fatherObject = null; } else { if (nowSerializeInfo.FatherSerializeInfo.IsIList) { nowSerializeInfo.FatherSerializeInfo.Index++; nowSerializeInfo.FatherSerializeInfo.SetInnerField(null); } else if (nowSerializeInfo.FatherSerializeInfo.IsIDictionary) { nowSerializeInfo.FatherSerializeInfo.SetInnerField(null); nowSerializeInfo.FatherSerializeInfo.Index++; } else { nowSerializeInfo.FatherSerializeInfo.Index++; } } bufStack.Pop(); if (fullLengthSchema) { if (readEnd >= totalLength) { break; } if (readEnd > brData.Position) { brData.SeekNextTo(readEnd); } } } else { if (nowSerializeInfo.TheType.IsArray) { nowSerializeInfo.IsArray = true; nowSerializeInfo.TheElementType = nowSerializeInfo.TheType.GetElementType(); nowSerializeInfo.Length_FieldInfo = (int)brData.ReadUInt32(); } else if (nowSerializeInfo.TheType.GetInterface("IList`1", false) != null) { nowSerializeInfo.IsIList = true; object[] ubas = nowSerializeInfo.TheType.GetCustomAttributes(false); if (ubas.Length > 0) { UseBaseArgument uba = ubas[0] as UseBaseArgument; if (uba != null) { nowSerializeInfo.TheElementType = nowSerializeInfo.TheType.BaseType.GetGenericArguments()[0]; } else { nowSerializeInfo.TheElementType = nowSerializeInfo.TheType.GetGenericArguments()[0]; } } else { nowSerializeInfo.TheElementType = nowSerializeInfo.TheType.GetGenericArguments()[0]; } nowSerializeInfo.Length_FieldInfo = (int)brData.ReadUInt32(); } else if (nowSerializeInfo.TheType.GetInterface("IDictionary`2", false) != null) { nowSerializeInfo.IsIDictionary = true; object[] ubas = nowSerializeInfo.TheType.GetCustomAttributes(false); if (ubas.Length > 0) { UseBaseArgument uba = ubas[0] as UseBaseArgument; if (uba != null) { nowSerializeInfo.TheElementType = nowSerializeInfo.TheType.BaseType.GetGenericArguments()[0]; nowSerializeInfo.TheValueType = nowSerializeInfo.TheType.BaseType.GetGenericArguments()[1]; } else { nowSerializeInfo.TheElementType = nowSerializeInfo.TheType.GetGenericArguments()[0]; nowSerializeInfo.TheValueType = nowSerializeInfo.TheType.GetGenericArguments()[1]; } } else { nowSerializeInfo.TheElementType = nowSerializeInfo.TheType.GetGenericArguments()[0]; nowSerializeInfo.TheValueType = nowSerializeInfo.TheType.GetGenericArguments()[1]; } nowSerializeInfo.Length_FieldInfo = (int)brData.ReadUInt32(); nowSerializeInfo.Keys = new object[nowSerializeInfo.Length_FieldInfo / 2]; } else { DynamicFieldInfo[] fis; lock (FI_Lookup) { if (FI_Lookup.ContainsKey(nowSerializeInfo.TheType)) { fis = FI_Lookup[nowSerializeInfo.TheType]; } else { PropertyInfo[] fi = nowSerializeInfo.TheType.GetProperties(AllInstanceBindingFlags).OrderBy(c => c.Name).ToArray(); List <DynamicFieldInfo> tempFis = new List <DynamicFieldInfo>(); for (int i = 0; i < fi.Length; i++) { PropertyInfo fiNow = fi[i]; object[] at = fiNow.GetCustomAttributes(typeof(System.NonSerializedAttribute), true); if (at.Length == 0) { tempFis.Add(new DynamicFieldInfo() { TheField = fiNow }); } } fis = tempFis.ToArray(); FI_Lookup.Add(nowSerializeInfo.TheType, fis); } } nowSerializeInfo.FieldInfos = fis; nowSerializeInfo.Length_FieldInfo = fis.Length; } if (!nowSerializeInfo.TheType.IsInterface) { nowSerializeInfo.CreatObject(); } if (fatherObject == null) { fatherObject = nowSerializeInfo.TheObject; } else { if (nowSerializeInfo.FatherSerializeInfo.IsIDictionary) { if (nowSerializeInfo.FatherSerializeInfo.Index < nowSerializeInfo.FatherSerializeInfo.Length_FieldInfo / 2) { //key值 nowSerializeInfo.FatherSerializeInfo.Keys[nowSerializeInfo.FatherSerializeInfo.Index] = nowSerializeInfo.TheObject; } else { //value值 nowSerializeInfo.FatherSerializeInfo.SetInnerField(nowSerializeInfo.TheObject); } } else { nowSerializeInfo.FatherSerializeInfo.SetInnerField(nowSerializeInfo.TheObject); } nowSerializeInfo.FatherSerializeInfo.Index++; } if (nowSerializeInfo.Length_FieldInfo != 0) { if (fullLengthSchema) { metablockLen = brData.TryReadMetaBlockLength(); nextSeekTo = brData.Position + metablockLen; //if (readEnd > 0 && readEnd < nextSeekTo) //{ // continue; //} } if (nowSerializeInfo.IsArray || nowSerializeInfo.IsIList) { innerSerializeInfo = new SerializeInfo(nowSerializeInfo.TheElementType, nextSeekTo); } else if (nowSerializeInfo.IsIDictionary) { innerSerializeInfo = new SerializeInfo(nowSerializeInfo.TheElementType, nextSeekTo); } else { DynamicFieldInfo tempDFI = nowSerializeInfo.FieldInfos[0]; innerSerializeInfo = new SerializeInfo(tempDFI.TheField.PropertyType, nextSeekTo); } innerSerializeInfo.FatherSerializeInfo = nowSerializeInfo; bufStack.Push(innerSerializeInfo); } } } } else //检查过 { if (nowSerializeInfo.Length_FieldInfo == nowSerializeInfo.Index) //检查完了 { bufStack.Pop(); if (fullLengthSchema) { if (readEnd >= totalLength) { break; } if (readEnd > 0 && readEnd > brData.Position) { brData.SeekNextTo(readEnd); } } } else { if (fullLengthSchema) { metablockLen = brData.TryReadMetaBlockLength(); nextSeekTo = brData.Position + metablockLen; if ((readEnd > 0 && readEnd < nextSeekTo)) { nowSerializeInfo.Index = nowSerializeInfo.Length_FieldInfo; brData.SeekAdd(-2); continue; } } if (nowSerializeInfo.IsArray || nowSerializeInfo.IsIList) { innerSerializeInfo = new SerializeInfo(nowSerializeInfo.TheElementType, nextSeekTo); } else if (nowSerializeInfo.IsIDictionary) { if (nowSerializeInfo.Index < nowSerializeInfo.Length_FieldInfo / 2) { innerSerializeInfo = new SerializeInfo(nowSerializeInfo.TheElementType, nextSeekTo); } else { innerSerializeInfo = new SerializeInfo(nowSerializeInfo.TheValueType, nextSeekTo); } } else { DynamicFieldInfo tempDFI = nowSerializeInfo.FieldInfos[nowSerializeInfo.Index]; innerSerializeInfo = new SerializeInfo(tempDFI.TheField.PropertyType, nextSeekTo); } innerSerializeInfo.FatherSerializeInfo = nowSerializeInfo; bufStack.Push(innerSerializeInfo); } } } if (fullLengthSchema) { readLength = totalLength; } else { readLength = brData.Position; } return(fatherObject); } catch (SerializeException se) { throw new SerializeException(objectType.ToString() + se.Message); } //catch (Exception e) { //throw new SerializeException(objectType.ToString() + "Data bytes and type not match" + e.Message); } }