How to read and write a dictionary of C # strings to a file?
I have a Dictionary object and I want to write to and read from disk. Ideally I would avoid any third party libraries. Is there an easy way to do this with regular C # 4?
ANSWER ACCEPTED.
Summary:
OPTION 1 - Using JavaScriptSerializer
Pros: No third party library required. In addition, a more modern format is used, i.e. Json
Cons: Difficult to read - not formed. It also requires a reference to the less commonly used System.Web.Extension assembly, even if the application has nothing to do with the web.
Decision:
Record:
File.WriteAllText("SomeFile.Txt", new JavaScriptSerializer().Serialize(dictionary));
Reading:
var dictionary = new JavaScriptSerializer()
.Deserialize<Dictionary<string, string>>(File.ReadAllText("SomeFile.txt"));
OPTION 2 - Using Linq to Xml
Pros: No third party library required. There is usually no need to add additional links. Easy to read.
Cons: XML is not as preferable as something more modern like JSON.
Record:
new XElement("root", d.Select(kv => new XElement(kv.Key, kv.Value)))
.Save(filename, SaveOptions.OmitDuplicateNamespaces);
Reading:
var dictionary = XElement.Parse(File.ReadAllText(filename))
.Elements()
.ToDictionary(k => k.Name.ToString(), v => v.Value.ToString());
OPTION 3 - Use JSON.NET
Pros: human readable. Modern format.
Cons: Third party library required.
Decision:
Record:
File.WriteAllText("SomeFile.Txt", JsonConvert.SerializeObject(dictionary));
Reading:
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>
(File.ReadAllText("SomeFile.txt"));
source to share
The easiest way to write a dictionary is to create a list of where each dictionary entry is converted to an XElement. Then you create a root XElement where list is the root value. The reason you want to use XElement is because then you can use a method Save
to store it on disk in XML format. An example of doing this in one line (where d is a Dictionary)
new XElement("root", d.Select(kv => new XElement(kv.Key, kv.Value)))
.Save(filename, SaveOptions.OmitDuplicateNamespaces);
To read a file into a dictionary, use the static Parse XElement method and pass it all the contents of the file that can be read with File.ReadAllText
. Parse returns an XElement object, root. Then you can iterate over the Elements()
root and convert it to a dictionary. You can do it in one line:
var d = XElement.Parse(File.ReadAllText(filename))
.Elements()
.ToDictionary(k => k.Name.ToString(), v => v.Value.ToString());
Here's a version of the above in methods:
public static void Store(IDictionary<string, string> d, string filename)
{
new XElement("root", d.Select(kv => new XElement(kv.Key, kv.Value)))
.Save(filename, SaveOptions.OmitDuplicateNamespaces);
}
public static IDictionary<string, string> Retrieve(string filename)
{
return XElement.Parse(File.ReadAllText(filename))
.Elements()
.ToDictionary(k => k.Name.ToString(), v => v.Value.ToString());
}
source to share
Without third party like JSON.Net use JavaScriptSerializer
:
File.WriteAllText("SomeFile.Txt", new JavaScriptSerializer().Serialize(dictionary));
Getting a dictionary from a file:
var dictionary = new JavaScriptSerializer()
.Deserialize<Dictionary<string, string>>(File.ReadAllText("SomeFile.txt"));
The only thing to remember is to add the link to System.Web.Extensions
in the project links and then you can use JavaScriptSerializer
afterusing System.Web.Script.Serialization;
Or with JSON.Net you can serialize a dictionary to JSON and then write it to a file and then deserialize it, like this:
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("1", "Some value 1");
dictionary.Add("2", "Something");
Saving the dictionary to a file:
string json = JsonConvert.SerializeObject(dictionary);
File.WriteAllText("SomeFile.Txt", json);
Getting a dictionary from a file:
Dictionary<string, string> previousDictionary =
JsonConvert.DeserializeObject<Dictionary<string, string>>
(File.ReadAllText("SomeFile.txt"));
For a comparison between the two see JSON.NET JsonConvert vs .NET JavaScriptSerializer
source to share