如何才能将A.EXE序列化出来的二进制文件能在B.EXE中反序列化.其中要注意什么?

解决方案 »

  1.   

    只要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();
        }
      

  2.   

    之前我序列化了一个结构,在同一个EXE中序列化和反序列化都正常.在另一个EXE中反序列化这个文件时出现"未找到....."总之百度说是命名空间不同导致的.没试出什么解决的方法来.我先试一下一楼的.谢谢
      

  3.   


    如果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);
        }
      

  4.   

    文字放在代码中显示不完整!
    上面的文字:
    如果BinaryFormatter、SoapFormatter和XmlSerializer都不能满足你的要求,那么可以通过在自定义类中实现接口来自定义序列化行为。这个接口只有一个方法,GetObjectData. 这个方法用于将对类对象进行串行化所需要的数据填进SerializationInfo对象。你使用的格式化器将构造SerializationInfo 对象,然后在串行化时调用GetObjectData. 如果类的父类也实现了ISerializable,那么应该调用GetObjectData的父类实现。如果你实现了ISerializable,那么还必须提供一个具有特定原型的构造器,这个构造器的参数列表必须与GetObjectData相同。这个构造器应该被声明为私有的或受保护的,以防止粗心的开发人员直接使用它。
      

  5.   

    两个EXE中都得要先知道目的类型的定义,如果 B.EXE 不知道目的类型的定义,那反序列化能成功吗?如果是[DataContract]序列化的也许可以
      

  6.   

    使用同一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;
            }
      

  7.   

    补充一下注意事项:
    被序列化的类型定义好后,以后最好不要更改程序集名称、类名、字段和属性名,这样会造成以前的文件无法正常反序列化。
    如果必须更改,可以指定BinaryFormatter.Binder,以兼容旧的序列化过的文件。
      

  8.   

    保证序列化和反序列化引用的是同样的一个定义就可以。
    跟几个EXE没关系。