2009-06-19 117 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); 
    } 
}