序列化与反序列化在两个EXE中如何使用

dylike 2010-05-15 08:54:36
如何才能将A.EXE序列化出来的二进制文件能在B.EXE中反序列化.其中要注意什么?
...全文
108 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
dylike 2010-05-15
  • 打赏
  • 举报
回复
OK了,原来不能单独放一个结构而要整个类.谢谢大家了.
problc 2010-05-15
  • 打赏
  • 举报
回复
保证序列化和反序列化引用的是同样的一个定义就可以。
跟几个EXE没关系。
zzx509 2010-05-15
  • 打赏
  • 举报
回复
补充一下注意事项:
被序列化的类型定义好后,以后最好不要更改程序集名称、类名、字段和属性名,这样会造成以前的文件无法正常反序列化。
如果必须更改,可以指定BinaryFormatter.Binder,以兼容旧的序列化过的文件。

wuyq11 2010-05-15
  • 打赏
  • 举报
回复
使用同一DLL文件。
在引用中添加引用DLL文件
public static string ObjectToXML( Object Instance )
{
MemoryStream stream = null;
TextWriter writer = null;
string ObjectXml = string.Empty;
try
{
stream = new MemoryStream();
writer = new StreamWriter( stream, Encoding.UTF8 );
Type t = Instance.GetType();
XmlSerializer serializer = new XmlSerializer( t );

XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
xsn.Add( string.Empty, string.Empty );
serializer.Serialize( writer, Instance, xsn );
int count = ( int )stream.Length;
byte[] arr = new byte[count];
stream.Seek( 0, SeekOrigin.Begin );
stream.Read( arr, 0, count );
UTF8Encoding utf = new UTF8Encoding();
ObjectXml = utf.GetString( arr ).Trim();
}
catch ( Exception ex )
{
string ss = ex.Message;
}
finally
{
if ( stream != null && stream.Length > 0 )
{
stream.Close();
}
if ( writer != null )
{
writer.Close();
}
}
return FormatXml( ObjectXml );
}
/// 反序列化XML字符串
public static object XMLToObject( string xml, Type t )
{
StringReader stream = null;
XmlTextReader reader = null;
Object o = null;
try
{
XmlSerializer serializer = new XmlSerializer( t );
stream = new StringReader( xml );
reader = new XmlTextReader( stream );
o = serializer.Deserialize( reader );
}
catch{}
finally
{
if ( stream != null )
{
stream.Close();
}
if ( reader != null )
{
reader.Close();
}
}
return o;
}
兔子-顾问 2010-05-15
  • 打赏
  • 举报
回复
你2个程序要定义一样尺寸的类,或是引用同一个类库提供同一个类。
这个基本没问题。你出错的是什么样子,数据不正确还是什么的?
websco 2010-05-15
  • 打赏
  • 举报
回复
两个EXE中都得要先知道目的类型的定义,如果 B.EXE 不知道目的类型的定义,那反序列化能成功吗?如果是[DataContract]序列化的也许可以
捷哥1999 2010-05-15
  • 打赏
  • 举报
回复
文字放在代码中显示不完整!
上面的文字:
如果BinaryFormatter、SoapFormatter和XmlSerializer都不能满足你的要求,那么可以通过在自定义类中实现接口来自定义序列化行为。这个接口只有一个方法,GetObjectData. 这个方法用于将对类对象进行串行化所需要的数据填进SerializationInfo对象。你使用的格式化器将构造SerializationInfo 对象,然后在串行化时调用GetObjectData. 如果类的父类也实现了ISerializable,那么应该调用GetObjectData的父类实现。

如果你实现了ISerializable,那么还必须提供一个具有特定原型的构造器,这个构造器的参数列表必须与GetObjectData相同。这个构造器应该被声明为私有的或受保护的,以防止粗心的开发人员直接使用它。
阿非 2010-05-15
  • 打赏
  • 举报
回复
需要引用相同的类库,要确保双方操作的是同一类型对象
捷哥1999 2010-05-15
  • 打赏
  • 举报
回复

如果BinaryFormatter、SoapFormatter和XmlSerializer都不能满足你的要求,那么可以通过在自定义类中实现接口来自定义序列化行为。这个接口只有一个方法,GetObjectData. 这个方法用于将对类对象进行串行化所需要的数据填进SerializationInfo对象。你使用的格式化器将构造SerializationInfo 对象,然后在串行化时调用GetObjectData. 如果类的父类也实现了ISerializable,那么应该调用GetObjectData的父类实现。

如果你实现了ISerializable,那么还必须提供一个具有特定原型的构造器,这个构造器的参数列表必须与GetObjectData相同。这个构造器应该被声明为私有的或受保护的,以防止粗心的开发人员直接使用它。

示例如下:
实现ISerializable的类:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

/**//// <summary>
/// Employee 的摘要说明
/// </summary>
[Serializable]
public class Employee:ISerializable
{
public int EmpId=100;
public string EmpName="刘德华";
[NonSerialized]
public string NoSerialString = "NoSerialString-Test";
public Employee()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
private Employee(SerializationInfo info, StreamingContext ctxt)
{
EmpId = (int)info.GetValue("EmployeeId", typeof(int));
EmpName = (String)info.GetValue("EmployeeName",typeof(string));
//NoSerialString = (String)info.GetValue("EmployeeString",typeof(string));
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("EmployeeId", EmpId);
info.AddValue("EmployeeName", EmpName);
//info.AddValue("EmployeeString", NoSerialString);
}
}

序列化方法:

public void SerializeCustom()
{
Employee mp = new Employee();
mp.EmpId = 10;
mp.EmpName = "邱枫";
mp.NoSerialString = "你好呀";
Stream steam = File.Open("c:\\temp3.dat", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(steam,mp);
steam.Close();
mp = null;
}

反序列化方法:
public void DeSerializeCustom()
{
Stream steam2 = File.Open("c:\\temp3.dat", FileMode.Open);
BinaryFormatter bf2 = new BinaryFormatter();

Employee mp2 = (Employee)bf2.Deserialize(steam2);
steam2.Close();
Console.Write(mp2.EmpId);
Console.Write(mp2.EmpName);
Console.Write(mp2.NoSerialString);
}
dylike 2010-05-15
  • 打赏
  • 举报
回复
之前我序列化了一个结构,在同一个EXE中序列化和反序列化都正常.在另一个EXE中反序列化这个文件时出现"未找到....."总之百度说是命名空间不同导致的.没试出什么解决的方法来.我先试一下一楼的.谢谢
捷哥1999 2010-05-15
  • 打赏
  • 举报
回复
只要A和B都知道文件的格式就可以了,例如:

[Serializable]
public class ClassToSerialize
{
public int id = 100;
public string name = "Name";
[NonSerialized]
public string Sex = "男";
}

//在A.exe中序列化:
public void SerializeNow()
{
ClassToSerialize c = new ClassToSerialize();
FileStream fileStream = new FileStream("c:\\temp.dat", FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
b.Serialize(fileStream, c);
fileStream.Close();
}


//在B.exe中反序列化
public void DeSerializeNow()
{
ClassToSerialize c = new ClassToSerialize();
c.Sex = "kkkk";
FileStream fileStream = new FileStream("c:\\temp.dat", FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryFormatter b = new BinaryFormatter();
c = b.Deserialize(fileStream) as ClassToSerialize;
Response.Write(c.name);
Response.Write(c.Sex);
fileStream.Close();
}

110,526

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧