c# class, method or what to parse a config file
New to the开发者_StackOverflow object orientated method of doing things and was just wondering what is the suggested method for doing this.
in my first question I asked about parsing a text file, and now with some good ideas (thank you guys) I am starting to write this part of the program.
the text file has multiple sections and multiple data types needed to be read in. This is going fine and as the complexity of the text file grows so the I am changing the code to adapt. But I will end up with 30 or so different variables/arrays/list etc that at least some will need to be global available to the program.
So I now have a chunk of code that at the moment is a method within the class that contains "main", and all the variables are global. (not nice I know).
I was thinking there must be a neater way to do this, I was thinking use a separate class, create an instance of this class and call the method with in this class that parses the text and populates the variables. Then simple call the class variables (any ones deemed to be public)from with in any other class I need to.
But then what do I know :) just looking for some ideas so i don't go to far down the road and have to turn back.
Cheers
Your instincts are good; the task of parsing a particular type of text file should be encapsulated in a class that is given some information about where to get the data, and produces an object graph representing the parsed data. As far as the input, a string with the filename is fine; better yet, pass in a Stream or StreamReader; the same parser can then digest the information from a file, memory block or network transmission.
Definitely break things down into repeatable chunks; if a file consists of a lot of similar lines that are parsed into subobjects, create a method to parse a single line and return the subobject.
Also make things as single-purpose as possible; if you have to deal with two types of text files, create one class for each file type, making them implement the same interface if possible. Then, you can implement what's called a Strategy pattern, where one object's job is to determine which of a series of other classes should be used to perform a task depending on the specifics.
To keep things simple, I would use the serializer class to do it:
Here is the example Config classes:
[Serializable]
public class Config
{
public int ValueOne { get; set; }
public string ValueTwo { get; set; }
public int[] LotsOfValues { get; set; }
public List<FurtherConfig> Other { get; set; }
}
[Serializable]
public class FurtherConfig
{
public int Value { get; set; }
}
And here is some example usage:
var config = new Config
{
ValueOne = 23,
ValueTwo = "Second Value",
LotsOfValues = new[] { 23, 34, 34 },
Other = new List<FurtherConfig> {
new FurtherConfig { Value = 567},
new FurtherConfig { Value = 98 }
}
};
var serializer = new XmlSerializer(typeof(Config));
//write out to file
using (var fw = File.OpenWrite("config.xml"))
serializer.Serialize(fw, config);
//read in from file
Config newConfig;
using (var fr = File.OpenRead("config.xml"))
newConfig = serializer.Deserialize(fr) as Config;
Console.WriteLine(newConfig.Other[1].Value); //prints 98
This is the serialized output:
<?xml version="1.0"?>
<Config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ValueOne>23</ValueOne>
<ValueTwo>Second Value</ValueTwo>
<LotsOfValues>
<int>23</int>
<int>34</int>
<int>34</int>
</LotsOfValues>
<Other>
<FurtherConfig>
<Value>567</Value>
</FurtherConfig>
<FurtherConfig>
<Value>98</Value>
</FurtherConfig>
</Other>
</Config>
For the parsing, I agree that XML serialization is a good way to do things.
As for how to access the data once it's in an object, consider a static class or the Singleton pattern.
If the format for the config file is not set in stone, then I would suggest utilizing the System.Xml.XmlSerializer class to save/load your config file as xml.
Pretty simple to save.. load will be left as an excersize for you:
using (FileStream file = new FileStream(path, FileMode.Create, FileAccess.something, FileShare.something))
{
XmlSerializer serializer = new XmlSerializer(this.getType());
serializer.serialize(file, this);
}
I may have goofed up the order of the parameters, and I'm a vb guy, but you get the idea.
精彩评论