问题描述
以下为示例代码,当输入15000时或者以上会产生System.OutOfMemoryException异常,另外同样的数据源,使用DataTable和Object执行序列化,得到的流长度差了两倍.如何才能突破BinaryFormatter的容量,另外DataTable和Object序列化后的不同如何解决.protectedvoidSerialize(introwCount){Console.WriteLine("时间:{0:yyyy-MM-ddHH:mm:ssddd},序列化数据,共{1}行.",DateTime.Now,rowCount);//创建数据源DataTabledt=newDataTable();for(intindex=0;index<100;index++){dt.Columns.Add(string.Format("Col{0}",index),typeof(string));}for(intj=0;j<2e4;j++){DataRownewRow=dt.NewRow();for(intindex=0;index<100;index++){newRow[string.Format("Col{0}",index)]=string.Format("数值({0})加数字({1})等于值({2})",index,j,index+j);}dt.Rows.Add(newRow);}Console.WriteLine("时间:{0:yyyy-MM-ddHH:mm:ssddd},已建立数据源.",DateTime.Now);//序列化MemoryStreamstream=newMemoryStream();newBinaryFormatter().Serialize(stream,dt);Console.WriteLine("时间:{0:yyyy-MM-ddHH:mm:ssddd},流长度{1:#,
解决方案二:
},类型DataTable.",DateTime.Now,stream.Length);//序列化objectobj=dtasobject;newBinaryFormatter().Serialize(stream,obj);Console.WriteLine("时间:{0:yyyy-MM-ddHH:mm:ssddd},流长度{1:#,
解决方案三:
},类型Object.",DateTime.Now,stream.Length);}
解决方案
解决方案四:
为了保证但序列化时能够有足够的类型信息,在你在序列化的时候,类型信息也是写入到序列化流内部的。由于DataTable和object的类型信息肯定不一样多,所以会造成序列化结果不一样。或者假设序列化结果完全一样,那么反序列化的结果难道会两样?那时候你又怎么区分是DataTable还是object呢?至于OOM,要看到底是哪里溢出了。一般来说改用64位的操作系统可以减少OOM的情况,另外就是尽可能不要序列化那么大的对象了。
解决方案五:
引用1楼lextm的回复:
为了保证但序列化时能够有足够的类型信息,在你在序列化的时候,类型信息也是写入到序列化流内部的。由于DataTable和object的类型信息肯定不一样多,所以会造成序列化结果不一样。或者假设序列化结果完全一样,那么反序列化的结果难道会两样?那时候你又怎么区分是DataTable还是object呢?至于OOM,要看到底是哪里溢出了。一般来说改用64位的操作系统可以减少OOM的情况,另外就是尽可能不要序列化那么大的对象了。
瞎说,楼主的代码错误MemoryStreamstream=newMemoryStream();newBinaryFormatter().Serialize(stream,dt);Console.WriteLine("时间:{0:yyyy-MM-ddHH:mm:ssddd},流长度{1:#,
解决方案六:
},类型DataTable.",DateTime.Now,stream.Length);//序列化objectobj=dtasobject;newBinaryFormatter().Serialize(stream,obj);同一个stream序列化同一个对象最后流大小当然是第一次序列化的一倍
解决方案七:
LS正确,序列化了两次
解决方案八:
确实同一个对象被序列化了两次,是个Bug.那么BinaryFormatter是否有分布序列化的方式呢,比如每次只写入固定长度的字节到流中,然后转存出去.
解决方案九:
BinaryFormatter.Serialize(Stream,obj);写入后是写到当前Stream的后面.不是重新生成一个Stream.