{"id":182,"date":"2012-03-13T22:24:06","date_gmt":"2012-03-13T14:24:06","guid":{"rendered":"https:\/\/www.techcoil.com\/blog\/?p=182"},"modified":"2018-09-03T21:34:30","modified_gmt":"2018-09-03T13:34:30","slug":"how-to-save-and-load-objects-to-and-from-file-in-c","status":"publish","type":"post","link":"https:\/\/www.techcoil.com\/blog\/how-to-save-and-load-objects-to-and-from-file-in-c\/","title":{"rendered":"How to save and load objects to and from file in C#"},"content":{"rendered":"<p>Persistency is almost always a requirement for applications that are meant for serious usage. Perhaps we want the data that our C# program had harvested or generated to be available everytime it runs. Or for that load of data that we are unable to send to a server to be remembered, so that we can try sending at a later time.<\/p>\n<p>Because most of the data that is held by a C# application at runtime is in the form of objects, it is convenient to be able to save and load objects to file directly. Such capability is dubbed <strong>object serialization<\/strong>, and like many other programming languages, C# has the facilities to perform object serialization for developers.<\/p>\n<h3>Remembering our friends<\/h3>\n<p>Suppose we want to write a C# program that can remember our friends' email addresses. Instead of <a href=\"http:\/\/www.techcoil.com\/blog\/quick-references\/my-experience-with-system-data-sqlite-in-c\/\" title=\"My experience with System.Data.SQLite in C#\" target=\"_blank\">using System.Data.SQLite<\/a>, let's use object serialization to achieve the data persistence aspect of our program. <\/p>\n<h3>The serializable Friend class<\/h3>\n<p>In order to be able to save and load objects, the class has to be indicated as being serializable. We mark a class with the <code>Serializable<\/code> attribute to indicate that we want to be able to save its objects:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nusing System;\r\nusing System.Text;\r\n\r\n&#x5B;Serializable]\r\npublic class Friend\r\n{\r\n    private string name;\r\n    private string email;\r\n\r\n    public Friend (string name, string email) {\r\n        this.name = name;\r\n        this.email = email;\r\n    }\r\n\r\n    public string Name\r\n    {\r\n        get\r\n        {\r\n            return this.name;\r\n        }\r\n\r\n        set\r\n        {\r\n            this.name = value;\r\n        }\r\n    } \/\/ end public string Name\r\n\r\n    public string Email\r\n    {\r\n        get\r\n        {\r\n            return this.email;\r\n        }\r\n        set\r\n        {\r\n            this.email = value;\r\n        }\r\n    } \/\/ end public string Email\r\n} \/\/ end public class Friend\r\n<\/pre>\n<p>Here, the <code>Friend<\/code> class is a data wrapper class that we will use to hold the name and email address of a particular friend. As we add more friends to our program, more <code>Friend<\/code> instances will be created. Such instances will be maintained by the <code>FriendsInformation<\/code> class.<\/p>\n<h3>The FriendsInformation class<\/h3>\n<p>Let's <a href=\"http:\/\/www.techcoil.com\/blog\/quick-references\/implementing-the-singleton-pattern-in-visual-basic-dot-net\/\" title=\"Implementing the Singleton Pattern in Visual Basic.Net\" target=\"_blank\">create a singleton class<\/a>, <code>FriendInformation<\/code>, that will be responsible for the saving and loading of information of our friends.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.IO;\r\nusing System.Runtime.Serialization;\r\nusing System.Runtime.Serialization.Formatters.Binary;\r\nusing System.Text;\r\n\r\npublic class FriendsInformation\r\n{\r\n\r\n    private static FriendsInformation friendsInformation;\r\n\r\n    private Dictionary&lt;string, Friend&gt; friendsDictionary;\r\n    private BinaryFormatter formatter;\r\n\r\n    private const string DATA_FILENAME = &quot;friendsinformation.dat&quot;;\r\n\r\n    public static FriendsInformation Instance()\r\n    {\r\n        if (friendsInformation == null) {\r\n            friendsInformation = new FriendsInformation();\r\n        } \/\/ end if\r\n\r\n        return friendsInformation;\r\n    } \/\/ end public static FriendsInformation Instance()\r\n\r\n    private FriendsInformation()\r\n    {\r\n        \/\/ Create a Dictionary to store friends at runtime\r\n        this.friendsDictionary = new Dictionary&lt;string, Friend&gt;();\r\n        this.formatter = new BinaryFormatter();\r\n    } \/\/ end private FriendsInformation()\r\n\r\n    public void AddFriend(string name, string email)\r\n    {\r\n        \/\/ If we already had added a friend with this name\r\n        if (this.friendsDictionary.ContainsKey(name))\r\n        {\r\n            Console.WriteLine(&quot;You had already added &quot; + name + &quot; before.&quot;);\r\n        }\r\n        \/\/ Else if we do not have this friend details \r\n        \/\/ in our dictionary\r\n        else\r\n        {\r\n            \/\/ Add him in the dictionary\r\n            this.friendsDictionary.Add(name, new Friend(name, email));\r\n            Console.WriteLine(&quot;Friend added successfully.&quot;);\r\n        } \/\/ end if\r\n    } \/\/ end public bool AddFriend(string name, string email)\r\n\r\n    public void RemoveFriend(string name)\r\n    {\r\n        \/\/ If we do not have a friend with this name\r\n        if (!this.friendsDictionary.ContainsKey(name))\r\n        {\r\n            Console.WriteLine(name + &quot; had not been added before.&quot;);\r\n        }\r\n        \/\/ Else if we have a friend with this name\r\n        else\r\n        {\r\n            if (this.friendsDictionary.Remove(name))\r\n            {\r\n                Console.WriteLine(name + &quot; had been removed successfully.&quot;);\r\n            }\r\n            else\r\n            {\r\n                Console.WriteLine(&quot;Unable to remove &quot; + name);\r\n            } \/\/ end if\r\n        } \/\/ end if\r\n    } \/\/ end public bool RemoveFriend(string name)\r\n\r\n    public void Save()\r\n    {\r\n        \/\/ Gain code access to the file that we are going\r\n        \/\/ to write to\r\n        try\r\n        {\r\n            \/\/ Create a FileStream that will write data to file.\r\n            FileStream writerFileStream = \r\n                new FileStream(DATA_FILENAME, FileMode.Create, FileAccess.Write);\r\n            \/\/ Save our dictionary of friends to file\r\n            this.formatter.Serialize(writerFileStream, this.friendsDictionary);\r\n\r\n            \/\/ Close the writerFileStream when we are done.\r\n            writerFileStream.Close();\r\n        }\r\n        catch (Exception) {\r\n            Console.WriteLine(&quot;Unable to save our friends' information&quot;);\r\n        } \/\/ end try-catch\r\n    } \/\/ end public bool Load()\r\n             \r\n    public void Load() \r\n    {\r\n     \r\n        \/\/ Check if we had previously Save information of our friends\r\n        \/\/ previously\r\n        if (File.Exists(DATA_FILENAME))\r\n        {\r\n\r\n            try\r\n            {\r\n                \/\/ Create a FileStream will gain read access to the \r\n                \/\/ data file.\r\n                FileStream readerFileStream = new FileStream(DATA_FILENAME, \r\n                    FileMode.Open, FileAccess.Read);\r\n                \/\/ Reconstruct information of our friends from file.\r\n                this.friendsDictionary = (Dictionary&lt;String, Friend&gt;)\r\n                    this.formatter.Deserialize(readerFileStream);\r\n                \/\/ Close the readerFileStream when we are done\r\n                readerFileStream.Close();\r\n\r\n            } \r\n            catch (Exception)\r\n            {\r\n                Console.WriteLine(&quot;There seems to be a file that contains &quot; +\r\n                    &quot;friends information but somehow there is a problem &quot; +\r\n                    &quot;with reading it.&quot;);\r\n            } \/\/ end try-catch\r\n\r\n        } \/\/ end if\r\n        \r\n    } \/\/ end public bool Load()\r\n\r\n    public void Print()\r\n    {\r\n        \/\/ If we have saved information about friends\r\n        if (this.friendsDictionary.Count &gt; 0)\r\n        {\r\n            Console.WriteLine(&quot;Name, Email&quot;);\r\n            foreach (Friend friend in this.friendsDictionary.Values)\r\n            {\r\n                Console.WriteLine(friend.Name + &quot;, &quot; + friend.Email);\r\n            } \/\/ end foreach\r\n        }\r\n        else\r\n        {\r\n            Console.WriteLine(&quot;There are no saved information about your friends&quot;);\r\n        } \/\/ end if\r\n    } \/\/ end public void Print()\r\n\r\n} \/\/ end public class FriendsInformation\r\n\r\n<\/pre>\n<h4>Encapsulating some facilitators<\/h4>\n<p>To facilitate the representation, addition and removal of friends information, we maintain an instance of the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/xfhwa508.aspx\" title=\"MSDN reference for http:\/\/msdn.microsoft.com\/en-us\/library\/xfhwa508.aspx\" target=\"_blank\"><code>System.Collections.Generic.Dictionary<\/code><\/a> class as an instance variable.<\/p>\n<p>On the other hand, to be able to serialize (save) and deserialize (load), we maintain an instance of the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.runtime.serialization.formatters.binary.binaryformatter(v=vs.71).aspx\" title=\"MSDN reference for System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\" target=\"_blank\"><code>System.Runtime.Serialization.Formatters.Binary.BinaryFormatter<\/code><\/a> class.<\/p>\n<h4>Adding new friend<\/h4>\n<p>The <code>AddFriend<\/code> method allows callers to add the name and email of a friend to the underlying <code>Dictionary<\/code> instance, via its <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/k7z0zy8k.aspx\" title=\"MSDN reference for Dictionary(Of TKey, TValue).Add Method\" target=\"_blank\"><code>Add<\/code><\/a> method. If we had already added a friend with the same name, the friend will not be added. <\/p>\n<h4>Removing a friend<\/h4>\n<p>The <code>RemoveFriend<\/code> method allows callers to remove a friend, based on his name, from our underlying <code>Dictionary<\/code> instance, via its <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/kabs04ac.aspx\" title=\"MSDN reference for Dictionary(Of TKey, TValue).Remove Method\" target=\"_blank\"><code>Remove<\/code><\/a> method. If there is no friend with the supplied name, no removal will take place.<\/p>\n<h4>Saving Friend objects to file<\/h4>\n<p>The <code>Save<\/code> method is all about <a href=\"http:\/\/www.techcoil.com\/blog\/quick-references\/how-to-write-to-file-in-c\/\" title=\"How to write to file in C#\" target=\"_blank\">writing to file<\/a>. We first obtain an instance of <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.io.filestream.aspx\" title=\"MSDN reference for System.IO.FileStream class\" target=\"_blank\"><code>System.IO.FileStream<\/code><\/a> which has write access to <code>friendsinformation.dat<\/code>. <\/p>\n<p>If we are successful in doing so, we use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.runtime.serialization.formatters.binary.binaryformatter.serialize.aspx\" title=\"MSDN reference for the BinaryFormatter.Serialize method\" target=\"_blank\">Serialize<\/a> method of our <code>BinaryFormatter<\/code> instance to save the entire <code>friendsDictionary<\/code> to <code>friendsinformation.dat<\/code>.<\/p>\n<h4>Loading Friend objects from file<\/h4>\n<p>On the contrary, the Load method is all about <a href=\"http:\/\/www.techcoil.com\/blog\/quick-references\/how-to-read-from-file-in-c\/\" title=\"How to read from file in C#\" target=\"_blank\">reading from file<\/a>. We first check whether there are previous calls to the <code>Save<\/code> method by checking the existence of <code>friendsinformation.dat<\/code>. <\/p>\n<p>If <code>friendsinformation.dat<\/code> exists, we first obtain an instance of <code>FileStream<\/code> that has read access to <code>friendsInformation.dat<\/code>. We then use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/b85344hz.aspx\" title=\"MSDN reference for BinaryFormatter.Deserialize Method \" target=\"_blank\">Deserialize<\/a> to read from the <code>FileStream<\/code> instance.  <\/p>\n<p>When the <code>Deserialize<\/code> method is called successfully, a <code>Dictionary<\/code> instance, which contains <code>Friend<\/code> objects that were previously saved to file, will be created. This <code>Dictionary<\/code> instance is then set to the <code>friendsDictionary<\/code> variable.<\/p>\n<h4>Printing of friends' information<\/h4>\n<p>The <code>Print<\/code> method allows us to inspect the <code>Friend<\/code> objects that are maintained by our program at runtime. It iterates the list of <code>Friend<\/code> objects and outputs the name and email. <\/p>\n<h3>A simple command line application<\/h3>\n<p>To sum up this post, let's create a command line application that we can use to remember the names and email addresses of our friends.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.IO;\r\nusing System.Text;\r\n\r\npublic class Program\r\n{\r\n    private static string programName = \r\n        Path.GetFileNameWithoutExtension(System.AppDomain.CurrentDomain.FriendlyName);\r\n\r\n    public static void Main(string&#x5B;] args)\r\n    {\r\n\r\n        if (args.Length &lt; 1)\r\n        {\r\n            PrintUsage();\r\n        }\r\n        else\r\n        {\r\n\r\n            FriendsInformation fi = FriendsInformation.Instance();\r\n            fi.Load();\r\n\r\n            String command = args&#x5B;0].ToLower();\r\n\r\n            if (command == &quot;list&quot;) \r\n            {\r\n                fi.Print();\r\n            }\r\n            else if (command == &quot;add&quot;) {\r\n\r\n                if (args.Length &gt;= 3)\r\n                {\r\n                    String name = args&#x5B;1];\r\n                    String email = args&#x5B;2];\r\n                    fi.AddFriend(name, email);\r\n                    fi.Save();\r\n                }\r\n                else\r\n                {\r\n                    PrintUsage();\r\n                    return;\r\n                } \/\/ end if\r\n                \r\n            }\r\n            else if (command == &quot;remove&quot;)\r\n            {\r\n\r\n                if (args.Length &gt;= 2)\r\n                {\r\n                    String name = args&#x5B;1];\r\n                    fi.RemoveFriend(name);\r\n                    fi.Save();\r\n                }\r\n                else\r\n                {\r\n                    PrintUsage();\r\n                    return;\r\n                } \/\/ end if\r\n\r\n            }\r\n            else\r\n            {\r\n                Console.WriteLine(&quot;Command not found: &quot; + command);\r\n                PrintUsage();\r\n            } \/\/ end if\r\n\r\n                \r\n        } \/\/ end if\r\n\r\n    } \/\/ end public static void Main(string&#x5B;] args)\r\n\r\n    public static void PrintUsage() \r\n    {\r\n        Console.WriteLine(&quot;Usage: &quot;);\r\n        Console.WriteLine(programName + &quot; list&quot;);\r\n        Console.WriteLine(programName + &quot; add &lt;name&gt; &lt;email&gt;&quot;);\r\n        Console.WriteLine(programName + &quot; remove &lt;name&gt;&quot;);\r\n    } \/\/ end public static void Main(string&#x5B;] args)\r\n} \/\/ end public class Program\r\n<\/pre>\n<p>The application accepts three commands via the command line:<\/p>\n<ol>\n<li><strong>list<\/strong> displays the names and email addresses of all our friends which we have added to our program.<\/li>\n<li><strong>add<\/strong> allows us to add a new friend to our program. <\/li>\n<li><strong>remove<\/strong> allows us to remove a friend from our program.<\/li>\n<\/ol>\n<p>For each of the 3 commands, the <code>FriendsInformation<\/code> singleton is created and called upon to attempt to load previously saved Friend objects into runtime. <\/p>\n<p>Except for the <strong>list<\/strong> command, the <code>Save<\/code> method of the <code>FriendsInformation<\/code> is called to save any changes made to the collection of Friend objects back into <code>friendsInformation.dat<\/code>.<\/p>\n<p>After several execution of the <strong>add<\/strong> and <strong>remove<\/strong> commands, <code>friendsInformation.dat<\/code> should appear in the same folder as our command line application. To check whether our command line application can remember (or forget) our friends, we can execute the <code>list<\/code> command.<\/p>\n<h3>Related posts<\/h3>\n<ul>\n<li><a href=\"http:\/\/www.techcoil.com\/blog\/quick-references\/how-to-read-from-file-in-c\/\" title=\"How to read from file in C#\">How to read from file in C#<\/a><\/li>\n<li><a href=\"http:\/\/www.techcoil.com\/blog\/quick-references\/how-to-write-to-file-in-c\/\" title=\"How to write to file in C#\">How to write to file in C#<\/a><\/li>\n<li><a href=\"http:\/\/www.techcoil.com\/blog\/quick-references\/my-experience-with-system-data-sqlite-in-c\/\" title=\"My experience with System.Data.SQLite in C#\">My experience with System.Data.SQLite in C#<\/a><\/li>\n<li><a href=\"http:\/\/www.techcoil.com\/blog\/quick-references\/implementing-client-server-communication-using-serialization-and-tcpip-in-c\/\" title=\"Implementing client-server communication using serialization and TCP\/IP in C#\">How to implement client-server communication using serialization and TCP\/IP in C#<\/a><\/li>\n<\/ul>\n\n      <ul id=\"social-sharing-buttons-list\">\n        <li class=\"facebook\">\n          <a href=\"https:\/\/www.facebook.com\/sharer\/sharer.php?u=https%3A%2F%2Fwp.me%2Fp245TQ-2W\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n            <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Facebook.png\" alt=\"Facebook icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"twitter\">\n          <a href=\"https:\/\/twitter.com\/intent\/tweet?text=&url=https%3A%2F%2Fwp.me%2Fp245TQ-2W&via=Techcoil_com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Twitter.png\" alt=\"Twitter icon\"> Tweet\n          <\/a>\n        <\/li>\n        <li class=\"linkedin\">\n          <a href=\"https:\/\/www.linkedin.com\/shareArticle?mini=1&title=&url=https%3A%2F%2Fwp.me%2Fp245TQ-2W&source=https:\/\/www.techcoil.com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/linkedin.png\" alt=\"Linkedin icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"pinterest\">\n          <a href=\"https:\/\/pinterest.com\/pin\/create\/button\/?url=https%3A%2F%2Fwww.techcoil.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F182&description=\" class=\"pin-it-button\" target=\"_blank\" role=\"button\" rel=\"nofollow\" count-layout=\"horizontal\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Pinterest.png\" alt=\"Pinterest icon\"> Save\n          <\/a>\n        <\/li>\n      <\/ul>\n    ","protected":false},"excerpt":{"rendered":"<p>Persistency is almost always a requirement for applications that are meant for serious usage. Perhaps we want the data that our C# program had harvested or generated to be available everytime it runs. Or for that load of data that we are unable to send to a server to be remembered, so that we can try sending at a later time.<\/p>\n<p>Because most of the data that is held by a C# application at runtime is in the form of objects, it is convenient to be able to save and load objects to file directly. Such capability is dubbed <strong>object serialization<\/strong>, and like many other programming languages, C# has the facilities to perform object serialization for developers.<\/p>\n","protected":false},"author":1,"featured_media":1189,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"footnotes":""},"categories":[375],"tags":[20,100,95,25],"jetpack_featured_media_url":"https:\/\/www.techcoil.com\/blog\/wp-content\/uploads\/C-Sharp-Logo.gif","jetpack_shortlink":"https:\/\/wp.me\/p245TQ-2W","jetpack-related-posts":[],"jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/182"}],"collection":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/comments?post=182"}],"version-history":[{"count":0,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/182\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media\/1189"}],"wp:attachment":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media?parent=182"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/categories?post=182"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/tags?post=182"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}