Binary Serialization

הפעם נדבר על Serialization בינארי, להבדיל מסוגים אחרים כמו Xml או מותאם אישית.
מה זה Serialization? בכמה מילים זה אומר שאני יכול לשמור אובייקט שלי לקובץ אוStream כדי שאני/מישהו אחר נוכל לטעון אותו בזמן אחר/מקום אחר.
Binary Serialization נקרא כך משום שהוא הופך את האובייקט שלי למערך של נתונים בינריים שאותם ניתן לשמור לקובץ או לשלוח לזרם כלשהו.
נגדיר מחלקה שאותה אנחנו רוצים לשמור

[Serializable]
public class Person
{
    public string firstName;
    public string lastName;
    public int age;
}

שימו לב למאפיין שהוספנו לפני הגדרת המחלקה - בעצם אומר שהמחלקה הזאת ניתנת לשמירה על ידי Serializer גם ההמשך פשוט מאוד, ניצור אובייקט מהמחלקה שלנו וניתן לו ערכים

Person p = new Person();

כעת ניצור הפניה לקובץ שבו נשמור את האובייקט שלנו

FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.OpenOrCreate);

ועכשיו ניצור אובייקט מהמחלקה שתעשה את השמירה בפועל

BinaryFormatter formatter = new BinaryFormatter ();

ונבצע את השמירה

formatter.Serialize(fs, p);

זהו... פשוט ביותר. יופי, עכשיו איך טוענים את מה ששמרנו? באותה קלות
ניצור הפניה לקובץ שבו שמרנו את האובייקט

FileStream fs = new FileStream(openFileDialog1.FileName,

ניצור את אותו אובייקט שיטען את הנתונים באותה צורה שיצרנו אותו לשמירת הנתונים

BinaryFormatter formatter = new BinaryFormatter ();

ופשוט נטען אותם

Person p = (Person)formatter.Deserialize(fs);

שימו לב רק שהטעינה מחזירה אובייקט מסוג object, ולכן עשינו casting לסוג Person
פשוט, נקי ומהיר

יש כמה אפשרויות מתקדמות למקרה שנרצה לשנות כמה דברים בתהליך
קודם כל אני יכול לציין איזה חלקים באובייקט שלי אני לא רוצה שישמרו לקובץ, לדוגמה סיסמה. בהגדרת המשתנה הזה במחלקה אני אוסיף לו מאפיין נוסף שיציין שאותו לא שומרים לקובץ

[NonSerialized] public string password;

דבר נוסף שעשוי להועיל הוא שניתן להתערב בתהליך של הטעינה מקובץ, כך שאם יש למשל נתון שלא שמרנו ואנחנו כן רוצים לתת לו ערך, למשל התאריך של היום, אז ניתן באותה פונקציה לעשות את זה לפני שמישהו משתמש באובייקט
לצורך זה אנחנו צריכים לממש את ה interface IDeserializationCallback במחלקה שאותה אנחנו שומרים\טוענים. פשוט נוסיף את המימוש להגדרת המחלקה

public class Person:IDeserializationCallback

יש בממשק הזה פונקציה אחת שחייבים לממש, והיא זאת שבעצם נקראת על ידי האובייקט שמבצע את הטעינה לאחר שהוא סיים את הטעינה, ובה אנחנו יכולים לעשות את שאר העבודה שאנחנו רוצים

public void OnDeserialization(object sender)
{
    this.today=DateTime.Now;
}

ודבר נוסף אחרון שניתן להשתמש בו, הוא להגדיר משתנה במחלקה כאופציונלי בעת הטעינה. מה הכוונה? נניח שפעם שמרנו את האובייקט והיום הוספנו לו עוד משתנים. בעת הטעינה נקבל אקספשן שחסר לו שדה. אם נוסיף מאפיין למשתנה שהוא אופציונלי, אם בעת הטעינה לא ימצא הערך הזה, הוא פשוט ידולג ויקבל ערך ברירת מחדל

[OptionalField] public string newField;

בפעם אחרת נדבר על xml serializer...
להורדת הפרוייקט

טוען נתונים...
אהבתם?
המליצו לאחרים!

נהניתם? בעיות? הערות?
אני רוצה לשמוע!
rss feed