分享+讨论:c#中类的序列化:一般化解决方法及最后的疑问
前一段时间因为频繁使用类的序列化,所以一直在思考如何能更方便的使用这个功能,现在把一段时间的学习过程和大家分享,同时还有个疑问向大家请教,如果您已经非常熟悉类的序列化,那么请您直接看第三部分。
什么是类的序列化?说白了,就是把一个类的实例转化成一段XML格式或二进制格式的数据,以便于网络传输、保存等操作。
同理,反序列化就是把XML或者二进制描述的对象还原成一个类的实例。
零、开始序列化
在C#中,要实现类的序列化并不难,以XML序列化为例,首先我们声明一个类:
[Serializable]
public class myClass
{
......
}
其中类声明上面的一句[Serializable]用来指示此类是可以序列化的,然后
引用两个namespace:
using System.IO;
using System.Xml.Serialization;
于是就可以执行下面代码:
myClass cls = new myClass();
XmlSerializer xmlSerializer = new XmlSerializer(cls.GetType());
MemoryStream stream = new MemoryStream();
xmlSerializer.Serialize(stream, cls);
byte[] buf = stream.ToArray();
string xml = Encoding.ASCII.GetString(buf);
stream.Close();
自此,序列化就完成了,XML序列保存在string xml;变量中。
上述代码不难理解,XmlSerializer类用来提供XML序列化的功能,xmlSerializer.Serialize(stream, cls)方法,可以把类cls序列化,并将XML序列存储在流stream中。
以上便是序列化的基本方法,可以满足我们的需求。但问题是如果我们经常需要对数个类进行序列化和反序列化,就要频繁的重复上述代码,能不能让类具备自己进行序列化的方法呢?
一、第一次尝试
我首先想到,可以写一个基类,提供进行序列化的方法,任何想实现序列化的类,只需要继承此类就可以具备此方法。于是构造抽象类:
public abstract class SerializableBaseClass
{
public virtual string XMLSerialize()
{
XmlSerializer xmlSerializer = new XmlSerializer(GetType()); //差异1
MemoryStream stream = new MemoryStream();
xmlSerializer.Serialize(stream, this); //差异2
byte[] buf = stream.ToArray();
string xml = Encoding.ASCII.GetString(buf);
stream.Close();
return xml;
}
}
上面一段代码和之前的代码只有两行不一样:
差异1:
cls.GetType()变成GetType():其中GetType()是获取当前实例的类型,在基类中调用GetType()得到的是当前实例的类型,而不是积累的类型。也就是说上述基类中调用GetType()不会得到” SerializableBaseClass”,更不会是”System.Object”,而是当前对象实例的类型。
差异2:
cls变成this:同理,this引用是指向当前实例的,只不过在基类中,不能使用this直接访问子类成员。当然通过类型转换可以达到此目的,但不在本文讨论范围内。所以Serialize(stream,this)会将整个对象序列化,而不会造成对象分割,只把基类给序列化了。
二、第二次尝试
到此为止,任何类只要集成了SerializableBaseClass就拥有了自我序列化的方法,但如何反序列化呢?我们在SerializableBaseClass类中再添加一个方法。
public object DeSerialize(string xmlString)
{
XmlSerializer xmlSerializer = new XmlSerializer(GetType());
byte[] buf = Encoding.ASCII.GetBytes(xmlString);
MemoryStream stream = new MemoryStream(buf);
object o = xmlSerializer.Deserialize(stream);
return o;
}
此方法就实现了类的反序列化,我们可以这样使用:
声明:
[Serializable]
public class myClass : SerializableBaseClass
{
……
}
使用:
myClass cls = new myClass();
string xml = cls. Serialize();
myClass cls1 = (myClass)cls. DeSerialize(xml);
这个使用乍一看没什么问题,但实际使用起来就很蹩脚
1、要想反序列化一个类,先要创建这个类的实例,只为了调用DeSerialize()
2、调用DeSerialize()返回的是object类型,需要进行类型转换
对于这两个问题,我也考虑过很久,如果把DeSerialize()定义为static,那么就不能使用GetType()方法,而其,也无法获取子类的类型。
三、最后的尝试
对于上述两个问题,想了很久,始终没想到解决办法,直到一天和朋友讨论c++STL的某个问题的时候,终于茅塞顿开,c#也是支持模板的呀,于是激动不已,改写SerializableBaseClass类:
[Serializable()]
public abstract class SerializableBaseClass<T>
{
public virtual string XMLSerialize()
{
XmlSerializer xmlSerializer = new XmlSerializer(GetType());
MemoryStream stream = new MemoryStream();
xmlSerializer.Serialize(stream, this);
byte[] buf = stream.ToArray();
string xml = Encoding.ASCII.GetString(buf);
stream.Close();
return xml;
}
public static T DeSerialize(string xmlString)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
byte[] buf = Encoding.ASCII.GetBytes(xmlString);
MemoryStream stream = new MemoryStream(buf);
T o = (T)xmlSerializer.Deserialize(stream);
return o;
}
}
这样,问题就不完美的解决了(确实不完美)。为什么不完美呢?那就看下面的代码:
[Serializable]
public class myClass : SerializableBaseClass<myClass>
{
……
}
使用:
myClass cls = myClass.DeSerialize(xmlData);
看似上述问题都解决了,但我还是心里不爽,因为每次定义一个继承SerializableBaseClass的类,还必须把自己的类名再写一遍,放在模板类型的参数里。有没有一种方案,可以让上述myClass类的声明默认模板参数就是自身myClass,而无须再写一遍<myClass>呢?或者还有更好的其他方法?欢迎讨论。
上述的所有代码,包括二进制序列化的方法,我已经做成了c#库,欢迎大家使用、指正,互相学习。
http://files.cnblogs.com/icyplayer/Icyplayer.rar
[解决办法]
不需要用抽象类继承这么麻烦,写个工具类即可...
public sealed class Serializer<T>{public static string ToString(T instance){//序列化}public static T Deserialize(string xmlString){//反序列化}}
[解决办法]
顶
[解决办法]
Jf
[解决办法]
顶下吧,马上就下班了,没有时间看了,太长了,老大啊
[解决办法]
不要滥用继承...这种需求不应该有“一次搞定一个抽象类,终生受益”的想法,耦合度太高...
序列化/反序列化这种操作应该是可选的操作而不应该是一个对象固有的方法...
[解决办法]
恩,学习。。
看起来好复杂
[解决办法]
下面是本人写的几个序列化反序列化,以及压缩的类,其实就是把很多已有的方法归类了下,共享出来给个参考:
public static class BinaryFormatSerializer { private static readonly BinaryFormatter InnerBinaryFormatter = new BinaryFormatter(); private readonly static MemoryStreamStack MemoryStreamStacker = new MemoryStreamStack(); public static byte[] Serialize(object obj, bool compress) { if (obj == null) { return null; } byte[] info; MemoryStream stream = MemoryStreamStacker.GetMemoryStream(); try { InnerBinaryFormatter.Serialize(stream, obj); stream.SetLength(stream.Position); info = stream.ToArray(); if (compress) { info = CompressHelper.CompressBytes(info); } } finally { MemoryStreamStacker.ReleaseMemoryStream(stream); } return info; } public static object Deserialize(byte[] info, bool decompress) { if (info == null || info.Length <= 0) { return info; } object ret; if (decompress) { info = CompressHelper.DeCompressBytes(info); } MemoryStream stream = MemoryStreamStacker.GetMemoryStream(); try { stream.Write(info, 0, info.Length); stream.Position = 0L; ret = InnerBinaryFormatter.Deserialize(stream); } finally { MemoryStreamStacker.ReleaseMemoryStream(stream); } return ret; } public static byte[] Serialize(object obj) { return Serialize(obj, false); } public static object Deserialize(byte[] info) { return Deserialize(info, false); } public static string SerializeToBase64String(object data, bool compress) { byte[] buffer = Serialize(data, compress); return Convert.ToBase64String(buffer); } public static object DeserializeFromBase64String(string baseString, bool decompress) { if (String.IsNullOrEmpty(baseString)) return null; byte[] buffer = Convert.FromBase64String(baseString); return Deserialize(buffer, decompress); } public static string SerializeToBase64String(object data) { return SerializeToBase64String(data, false); } public static object DeserializeFromBase64String(string baseString) { return DeserializeFromBase64String(baseString, false); } }
[解决办法]
上面是二进制的,这个是datdacontract序列化成二进制的:
public static class DataContractFormatSerializer
{
public static string SerializeToBase64String <T>(T obj, bool compress)
{
byte[] ret = Serialize <T>(obj, compress);
return Convert.ToBase64String(ret);
}
public static byte[] Serialize <T>(T obj, bool compress)
{
if (obj == null)
{
return null;
}
byte[] info;
using (MemoryStream stream = new MemoryStream())
{
DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
using (XmlDictionaryWriter binaryDictionaryWriter = XmlDictionaryWriter.CreateBinaryWriter(stream))
{
serializer.WriteObject(binaryDictionaryWriter, obj);
binaryDictionaryWriter.Flush();
}
info = stream.ToArray();
if (compress)
{
info = CompressHelper.CompressBytes(info);
}
}
return info;
}
public static T DeserializeFromBase64String <T>(string baseString, bool decompress)
{
if (String.IsNullOrEmpty(baseString))
return default(T);
byte[] buffer = Convert.FromBase64String(baseString);
return Deserialize <T>(buffer, decompress);
}
public static T Deserialize <T>(byte[] info, bool decompress)
{
T ret = default(T);
if (info == null || info.Length <= 0)
{
return ret;
}
if (decompress)
{
info = CompressHelper.DeCompressBytes(info);
}
using (MemoryStream stream = new MemoryStream(info))
{
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
using (XmlDictionaryReader binaryDictionaryReader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max))
{
ret = (T)serializer.ReadObject(binaryDictionaryReader);
}
}
return ret;
}
}
public static class DataContractXmlSerializer { public static string Serialize<T>(T obj) { if (obj == null) { return null; } string ret = ""; using (MemoryStream stream = new MemoryStream()) { DataContractSerializer serializer = new DataContractSerializer(obj.GetType()); using (XmlDictionaryWriter binaryDictionaryWriter = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8)) { serializer.WriteObject(binaryDictionaryWriter, obj); binaryDictionaryWriter.Flush(); } ret = Encoding.UTF8.GetString(stream.ToArray()); } return ret; } public static T Deserialize<T>(string xml) { T ret = default(T); if (string.IsNullOrEmpty(xml)) { return ret; } using (MemoryStream stream = new MemoryStream()) { byte[] bytes = Encoding.UTF8.GetBytes(xml); stream.Write(bytes, 0, bytes.Length); stream.Position = 0L; DataContractSerializer serializer = new DataContractSerializer(typeof(T)); using (XmlDictionaryReader binaryDictionaryReader = XmlDictionaryReader.CreateTextReader(stream, XmlDictionaryReaderQuotas.Max)) { ret = (T)serializer.ReadObject(binaryDictionaryReader); } } return ret; } }
[解决办法]
这个是viewstate序列化使用的类
public static class ObjectStateFormatSerializer { private static readonly ObjectStateFormatter InnerStateFormatter = new ObjectStateFormatter(); private readonly static MemoryStreamStack MemoryStreamStacker = new MemoryStreamStack(); public static string SerializeToBase64String(object obj, bool compress) { byte[] bytes = Serialize(obj, compress); return Convert.ToBase64String(bytes); } public static T DeserializeFromBase64String<T>(string baseString, bool compress) { if (String.IsNullOrEmpty(baseString)) return default(T); byte[] buf = Convert.FromBase64String(baseString); return Deserialize<T>(buf, compress); } public static byte[] Serialize(object obj, bool compress) { if (obj == null) { return null; } byte[] buf = null; MemoryStream stream = MemoryStreamStacker.GetMemoryStream(); try { InnerStateFormatter.Serialize(stream, obj); stream.SetLength(stream.Position); buf = stream.ToArray(); if (compress) { buf = CompressHelper.CompressBytes(buf); } } finally { MemoryStreamStacker.ReleaseMemoryStream(stream); } return buf; } public static T Deserialize<T>(byte[] info, bool compress) { T ret = default(T); if (info == null || info.Length <= 0) { return ret; } if (compress) { info = CompressHelper.DeCompressBytes(info); } MemoryStream stream = MemoryStreamStacker.GetMemoryStream(); try { stream.Write(info, 0, info.Length); stream.Position = 0L; ret = (T)InnerStateFormatter.Deserialize(stream); } finally { MemoryStreamStacker.ReleaseMemoryStream(stream); } return ret; } }
[解决办法]
这个是普通xml序列化的:
public static class XmlSerializationHelper
{
public static string Serialize(object obj, string xsdNs, string xsiNs)
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("xsd", xsdNs);
ns.Add("xsi", xsiNs);
XmlSerializer serializer = new XmlSerializer(obj.GetType());
StringBuilder sb = new StringBuilder();
TextWriter writer = new StringWriter(sb);
serializer.Serialize(writer, obj, ns);
sb.Replace("utf-16", "utf-8");
return sb.ToString();
}
public static object Deserialize(string xmlText, Type type)
{
XmlSerializer serializer = new XmlSerializer(type);
TextReader reader = new StringReader(xmlText);
object result = serializer.Deserialize(reader);
return result;
}
public static string RemoveEmptyTags(string sXML)
{
System.Text.StringBuilder sb = new StringBuilder();
sb.Append(" <?xml version=\"1.0\" encoding=\"UTF-8\"?>");
sb.Append(" <xsl:stylesheet ");
sb.Append(" version=\"1.0\" ");
sb.Append(" xmlns:msxsl=\"urn:schemas-microsoft-com:xslt\"");
sb.Append(" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">");
sb.Append(" <xsl:output method=\"xml\" version=\"1.0\" encoding=\"UTF-8\"/>");
sb.Append(" <!-- Whenever you match any node or any attribute -->");
sb.Append(" <xsl:template match=\"node()|@*\">");
sb.Append(" <!-- Copy the current node -->");
sb.Append(" <xsl:if test=\"normalize-space(.) != '' or normalize-space(./@*) != \'' \">");
sb.Append(" <xsl:copy>");
sb.Append(" <!-- Including any attributes it has and any child nodes -->");
sb.Append(" <xsl:apply-templates select=\"@*|node()\"/>");
sb.Append(" </xsl:copy>");
sb.Append(" </xsl:if>");
sb.Append(" </xsl:template>");
sb.Append(" </xsl:stylesheet>");
return TransXMLStringThroughXSLTString(sXML, sb.ToString());
}
private static string TransXMLStringThroughXSLTString(string sXML, string sXSLT)
{
//This is the logic of the application.
//XslCompiledTransform objTransform = new XslCompiledTransform();
//XmlDocument objDocument = new XmlDocument();
//StringWriter objStream = new StringWriter();
////objDocument.Load(strAppPath+"BookFair.xml");
//objDocument.LoadXml(sXML);
//StringReader stream = new StringReader(sXSLT);
//XmlReader xmlR = new XmlTextReader(stream);
//objTransform.Load(xmlR, null, null);
//objTransform.Transform(xmlR, null,
// objStream, null);
//return objStream.ToString().Replace(@"encoding=""utf-16""?>", @"encoding=""utf-8""?>");
throw new NotImplementedException();
}
public static string PrettyPrint(string xmlText)
{
String result = string.Empty;
try
{
MemoryStream ms = new MemoryStream();
XmlTextWriter w = new XmlTextWriter(ms, Encoding.Unicode);
XmlDocument d = new XmlDocument();
// Load the XmlDocument with the XML.
d.LoadXml(xmlText);
w.Formatting = Formatting.Indented;
// Write the XML into a formatting XmlTextWriter
d.WriteContentTo(w);
w.Flush();
ms.Flush();
// Have to rewind the MemoryStream in order to read
// its contents.
ms.Position = 0;
// Read MemoryStream contents into a StreamReader.
StreamReader sr = new StreamReader(ms);
// Extract the text from the StreamReader.
String formattedXML = sr.ReadToEnd();
result = formattedXML;
ms.Close();
w.Close();
}
catch (Exception err)
{
Exception e = new Exception(err.Message + " " + "XML Input: " + xmlText,err.InnerException);
throw(e);
}
return result;
}
}
public static class CompressHelper
{
private readonly static MemoryStreamStack MemoryStreamStacker = new MemoryStreamStack();
public static string CompressBytesToBase64String(byte[] buffer)
{
if (buffer == null || buffer.Length == 0)
{
return "";
}
byte[] compressedData = CompressBytes(buffer);
return System.Convert.ToBase64String(compressedData, 0, compressedData.Length);
}
public static string ConvertBytesToBase64String(byte[] buffer)
{
if (buffer == null || buffer.Length == 0)
{
return "";
}
return System.Convert.ToBase64String(buffer, 0, buffer.Length);
}
public static byte[] ConvertBase64StringToBytes(string deCompressString)
{
if (string.IsNullOrEmpty(deCompressString))
{
return new byte[0];
}
byte[] buffer = System.Convert.FromBase64String(deCompressString);
return buffer;
}
public static byte[] DeCompressBase64StringToBytes(string deCompressString)
{
if (string.IsNullOrEmpty(deCompressString))
{
return new byte[0];
}
byte[] buffer = System.Convert.FromBase64String(deCompressString);
byte[] ret = DeCompressBytes(buffer);
return ret;
}
public static byte[] CompressBytes(byte[] buffer)
{
if (buffer == null || buffer.Length == 0)
{
return buffer;
}
byte[] compressedData;
MemoryStream ms = MemoryStreamStacker.GetMemoryStream();
try
{
using (DeflateStream compressedzipStream = new DeflateStream(ms, CompressionMode.Compress, true))
{
compressedzipStream.Write(buffer, 0, buffer.Length);
}
ms.SetLength(ms.Position);
//如果得到的结果长度比原来还大,则不需要压宿,返回原来的,并带上一位标识数据是否已压宿过
if (ms.Length >= buffer.Length)
{
compressedData = new byte[buffer.Length + 1];
buffer.CopyTo(compressedData, 0);
compressedData[compressedData.Length - 1] = 0;
}
else
{
compressedData = new byte[ms.Length + 1];
ms.ToArray().CopyTo(compressedData, 0);
compressedData[compressedData.Length - 1] = 1;
}
//ms.Close();
}
finally
{
MemoryStreamStacker.ReleaseMemoryStream(ms);
}
return compressedData;
}
private static MemoryStream DeCompressMemoryToMemory(MemoryStream ms)
{
MemoryStream data = MemoryStreamStacker.GetMemoryStream();
using (DeflateStream zipStream = new DeflateStream(ms, CompressionMode.Decompress))
{
byte[] writeData = new byte[8192];
// Use the ReadAllBytesFromStream to read the stream.
while (true)
{
int size = zipStream.Read(writeData, 0, writeData.Length);
if (size > 0)
{
data.Write(writeData, 0, size);
}
else
{
break;
}
}
}
return data;
}
public static byte[] DeCompressBytes(byte[] buffer)
{
if (buffer == null || buffer.Length <= 0)
{
return buffer;
}
byte[] bytes = new byte[buffer.Length - 1];
Array.Copy(buffer, bytes, bytes.Length);
//如果最后一位是0,说明没有被压宿,那么也不需要解压速
if (buffer[buffer.Length - 1] == 0)
{
return bytes;
}
using (MemoryStream ms = new MemoryStream(buffer))
{
MemoryStream stream = null;
try
{
stream = DeCompressMemoryToMemory(ms);
stream.SetLength(stream.Position);
bytes = stream.ToArray();
}
finally
{
MemoryStreamStacker.ReleaseMemoryStream(stream);
}
}
return bytes;
}
}
public class MemoryStreamStack { private Stack<MemoryStream> _streams = new Stack<MemoryStream>(); public MemoryStream GetMemoryStream() { MemoryStream stream = null; if (_streams.Count > 0) { lock (_streams) { if (_streams.Count > 0) { stream = (MemoryStream)_streams.Pop(); } } } if (stream == null) { stream = new MemoryStream(0x800); } return stream; } public void ReleaseMemoryStream(MemoryStream stream) { if (stream == null) { return; } stream.Position = 0L; stream.SetLength(0L); lock (_streams) { _streams.Push(stream); } } ~MemoryStreamStack() { foreach (MemoryStream memory in _streams) { memory.Dispose(); } _streams.Clear(); _streams = null; } }
[解决办法]
序列化压缩等完全可以封装静态的helper,除非自定义自己的类的序列化方式,需要继承什么的
上面这些类,是我从学着编程开始慢慢积累起来的,对于项目中用到这些东西能快速使用,但序列化压缩要慎用,他们很耗资源的,特别是对cpu和内存。
其实最省的序列化方式,莫过于用分隔符把每个属性format成一个字符串,省空间也剩速度。
[解决办法]
学习了
[解决办法]
关注下
[解决办法]
这是设计思想有问题
想想吧 MS 为什么用 interface ISerializable 而没有像你这样做成一个 base class.
[解决办法]
关注
[解决办法]
学习下
[解决办法]
学习一下,关注关注
[解决办法]
学习
[解决办法]
回帖是一种美德!传说每天回帖即可获得 10 分可用分!
[解决办法]
谢谢分享,学习了
[解决办法]
学习
[解决办法]
以前也用序列化做了一个程序,但是个人认为序列化与反序列化虽然简单,但是也存在着反序列化时的一些不可控性
[解决办法]
用Object做参数不就可以了
[解决办法]
关注下。
[解决办法]
晕贴那么多代码。
[解决办法]
强啊
[解决办法]
把报表的格式导成二进制文件,是不是也是一种序列化呢?
最近看别人能把报表的格式,导成二进制文件,感觉比较神奇,
看了贴子..感觉应该很类似的吧...
学习了....
[解决办法]
学习
[解决办法]
前几天自己也写了一个,晒晒:
using System;using System.Collections.Generic;using System.Text;using System.Xml;using System.Xml.Serialization;namespace FileManager{ public class SerialzeX<T> { private string m_file; public SerialzeX(string filename) { m_file = filename; } public T GetSerialze() { try { XmlSerializer xs = new XmlSerializer(typeof(T)); using (XmlReader reader = XmlReader.Create(m_file)) { object res = xs.Deserialize(reader); return (T)res; } } catch { return default(T); } } public void SetSerialze(T obj) { try { XmlSerializer xs = new XmlSerializer(typeof(T)); using (XmlWriter writer = XmlWriter.Create(m_file)) { xs.Serialize(writer, obj); } } catch { } } }}
[解决办法]
学习!
[解决办法]
不看好。
C#是单继承的,基类名额只有一个,很宝贵
[解决办法]
鼓励一下
[解决办法]
这样的序列化比较容易出问题的,为什么这么简单MS没有做?
建议在原型设计的时候,用如下的类测试一下。
A、B、C、D、E、F都是可序列化的引用类型
public class A
{
B typeb;
C typec;
D typed;
E[] typee;
List<F> typef;
}
个人不建议对序列号做封装,简单序列化除外。
[解决办法]
Mark! study~
[解决办法]
看看来吖
[解决办法]
happy new year
[解决办法]
mark
[解决办法]
up
[解决办法]
学习
[解决办法]
学习
[解决办法]
序列化用的不多,过来学习学习
[解决办法]
xuexi
[解决办法]
哇
好长啊 我的眼睛都看花了啊
[解决办法]
Mark! study~
[解决办法]
codeproject上面有一个关于序列化的开源项目RawSerializer,若比较在意序列化/反序列化的效率,尤其是在网络传输,强烈建议去看看那篇。
我工作中一直使用这个库。
.NET自带的序列化器对DataTable的序列化/反序列化效率非常糟糕,不知道它自带的byte[]序列化是不是仅仅把xml文本转为了byte[]?这个我没有详细研究过,懂的请不吝赐教,说明一下.NET的二进制序列化的工作原理。
[解决办法]
mark
[解决办法]
学习
[解决办法]
mark
[解决办法]
序列化为byte[]比较方便。比如保存到数据库的某个字段。
[解决办法]
学习了
[解决办法]
这个问题用泛型可以得到完美的解决!
[解决办法]
我自己写的泛型序列化的方法:
public static byte[] Binaryobjecttobyte<T>( T t) //将对象序列化成字节数组
{
using (MemoryStream mem = new MemoryStream())
{
BinaryFormatter binary = new BinaryFormatter();
binary.Serialize(mem, t);
return mem.ToArray();
}
}
public static T Binarybytetoobject<T>( byte[] buff)//将字节数组反序列化成对象
{
using (MemoryStream mem = new MemoryStream(buff))
{
mem.Position = 0;
BinaryFormatter binary = new BinaryFormatter();
return (T)binary.Deserialize(mem);
}
}
[解决办法]
很名求吗
------解决方案--------------------
今天用了一下序列化,类中的对象属性有中文字符串,在反序列化时出现异常。
提示信息:未处理DecoderFallbackException,
无法将位于索引6处的字节[E8][8B]由指定的代码页转换为Unicode。
大家帮忙分析一下是什么原因呀?类中有中文字符序列化需要特殊处理吗?
[解决办法]
顶下吧,马上就下班了,没有时间看了,太长了,老大啊
[解决办法]
顶下吧
[解决办法]
学习!
[解决办法]
UP
[解决办法]
学习 !!!
[解决办法]
学习了.,.
[解决办法]
mark
[解决办法]
学习.
[解决办法]
回帖是一种美德!传说每天回帖即可获得 10 分可用分!
[解决办法]
mark
[解决办法]
学习~~~~~~
[解决办法]
序列话和反序列化和具体的类没有关系的,不需要用继承
[解决办法]
学习啦~~~
[解决办法]
学习
[解决办法]
up
[解决办法]
mark
[解决办法]
写得好,正好学一下。
[解决办法]
学习
[解决办法]
xue xi le
[解决办法]
学习下
[解决办法]
顶
[解决办法]
这段也在学习这方面的东西,感觉有点混,有点乱。还得理一下思路。授教了。
[解决办法]
up
[解决办法]
路过学习..
[解决办法]
Mark!~!
[解决办法]
学习!!
[解决办法]
学习!!
[解决办法]
顶起
[解决办法]
学习是唯一的出路!
[解决办法]
好贴,向高人们学习。。
[解决办法]
顶.........
[解决办法]
~~
[解决办法]
好贴,向高人们学习。。
------解决方案--------------------
顶一下再看
[解决办法]
mark
[解决办法]
序列化后的程序会变慢的!!
[解决办法]
mark先
[解决办法]
study