2009-06-19 84 views
2

我有序列化问题。 我想将一个对象转换为一个字符串,反之亦然。 我有两个实用方法:序列化问题

public 
static byte[] Serialize(Object o) 
{ 
    MemoryStream ms = new MemoryStream(); 
    BinaryFormatter bf1 = new BinaryFormatter(); 
    bf1.Serialize(ms, o); 
    byte[] buffer = ms.ToArray(); 
    //string retStr = Convert.ToBase64String(buffer); 
    return buffer; 
} 

public static object Deserialize(byte[] TheByteArray) 
{ 
    //byte[] TheByteArray = Convert.FromBase64String(ParamStr); 
    MemoryStream ms = new MemoryStream(TheByteArray); 
    BinaryFormatter bf1 = new BinaryFormatter(); 
    ms.Position = 0; 
    return bf1.Deserialize(ms); 
} 

我的测试代码:

Student obj = new Student(); 
obj.UserName = "Admin"; 
obj.Password = "Password"; 
obj.lessonIds = new int[] { 1, 2, 3, 4, 5 }; 
obj.lessonNames= new string[] { "Spanish", "Maths" }; 
obj.Id= 43; 
byte[] retByteArray = Crypto.Serialize(obj); 

Student objNew = new Student(); 
objNew = (Student)Crypto.Deserialize(retByteArray); 

此代码不起作用。 错误消息是:异常已被调用的目标抛出。 分析完成前遇到的流结束。

结束我的主要目的是转换对象转换成字符串,但即使我不能把它你的时候转换成字节数组

+0

什么是Cryto指呢? – 2009-06-19 12:24:22

+0

这不是bug,但你不需要 Student objNew = new Student();在调用反序列化之前。你只是创建一个对象,然后用另一个替换它。 – 2009-06-19 12:32:00

+0

重新评论 - 然后简单地说,你正在反序列化它不正确。它真的*不值得尝试编写自己的序列化代码 - 我强烈建议尝试protobuf-net(注意:我是作者,但它是免费的)。花几秒钟时间才能应用您的示例,从而提供非常高效的结果,而不会产生这些烦人的流错误。 – 2009-06-19 18:28:08

回答

0

你可能会从比赛条件下的痛苦,因为你没有关闭存储流或格式化程序”重新完成序列化。

试试这个:

public 
static byte[] Serialize(Object o) 
{ 
    using (MemoryStream ms = new MemoryStream()) 
    { 
     BinaryFormatter bf1 = new BinaryFormatter(); 
     bf1.Serialize(ms, o); 
     byte[] buffer = ms.ToArray(); 
     //string retStr = Convert.ToBase64String(buffer); 
    } 
    return buffer; 
} 

public static object Deserialize(byte[] TheByteArray) 
{ 
    //byte[] TheByteArray = Convert.FromBase64String(ParamStr); 
    using (MemoryStream ms = new MemoryStream(TheByteArray)) 
    { 
     BinaryFormatter bf1 = new BinaryFormatter(); 
     ms.Position = 0; 
     var result = bf1.Deserialize(ms); 
    } 
    return result; 
} 
1

我刚刚尝试了全新的代码,它的工作的优良不过,你需要确保学生类的定义被标记为[Serializable接口]

[Serializable] 
public class Student 
{ 
    public string UserName; 
    public string Password; 
    public int[] lessonIds; 
    public string[] lessonNames; 
    public int Id; 
    public Student() { } 
} 
0

这段代码对我来说很完美(我只是简单地加了一个缺失的Student这个类,这个代码实际上代表了你的真正的代码,特别是缓冲区处理(可能是文件IO)是我的第一个怀疑。但该错误不在您发布的代码中......它可以正常工作。

顺便说一下...... BinaryFormatter可能很脆弱,尤其是在不同的版本周围 - 您可能需要考虑替代串行器。如果您有兴趣,请索取更多信息。

这是可运行:

using System.IO; 
using System.Runtime.Serialization.Formatters.Binary; 
using System; 
static class Crypto 
{ 
    static byte[] Serialize(object o) 
    { 
     MemoryStream ms = new MemoryStream(); 
     BinaryFormatter bf1 = new BinaryFormatter(); 
     bf1.Serialize(ms, o); 
     byte[] buffer = ms.ToArray(); 
     //string retStr = Convert.ToBase64String(buffer); 
     return buffer; 
    } 

    public static object Deserialize(byte[] TheByteArray) 
    { 
     //byte[] TheByteArray = Convert.FromBase64String(ParamStr); 
     MemoryStream ms = new MemoryStream(TheByteArray); 
     BinaryFormatter bf1 = new BinaryFormatter(); 
     ms.Position = 0; 
     return bf1.Deserialize(ms); 
    } 
    [Serializable] 
    class Student 
    { 
     public string UserName { get; set; } 
     public string Password { get; set; } 
     public int[] LessonIds { get; set; } 
     public string[] LessonNames { get; set; } 
     public int Id { get; set; } 
    } 
    static void Main() 
    { 
     Student obj = new Student(); 
     obj.UserName = "Admin"; 
     obj.Password = "Password"; 
     obj.LessonIds = new int[] { 1, 2, 3, 4, 5 }; 
     obj.LessonNames = new string[] { "Spanish", "Maths" }; 
     obj.Id = 43; 
     byte[] retByteArray = Crypto.Serialize(obj); 

     Student objNew = (Student)Crypto.Deserialize(retByteArray); 
    } 
}