Click to See Complete Forum and Search --> : [RESOLVED] Creating file for XmlReader
mwpeck
May 30th, 2008, 03:52 AM
I tried changing the following in the GameSettings.Create():
using( XmlReader reader = XmlReader.Create( Assembly.GetExecutingAssembly( ).Location + ".config" ) )
///changed it to
using( XmlReader reader = XmlReader.Create(fullConfigFile) )
The problem is it is NOT creating the file, even if I create an empty file with that name it gives a different crash.....I cannot get it to create the file automatically if it doesnt exist like it does in the first part (the one with Assembly...blahblahblah). What am I doing wrong with it? Only way I can get it to work fine is if I create the file myself then add the schema of the normal config file to it.
the .Create() method is a static method that creates a XmlReader object. It doesn't create a file. We used this before because the file existed. If the file doesn't exist you need to use something else.
Oddly, if I delete the file with the old .Create() (where it uses program.exe.config) it remakes it when I load the program again, so I figured it also created the file if it didnt exist.
PS: Those who dont understand this, I had PMed Arjay about this, he asked I post it here.
Arjay
May 30th, 2008, 12:20 PM
First of all I need to explain how GameSettings.exe.config gets created.
This file (or any file with the format of <program>.exe.config) is created from the App.Config file in the project. The C# environment takes the App.Config file and renames it and copies it over to the output folder.
Thats why if you delete the GameSettings.exe.config file, it gets recreated.
Okay, now if you want to create a different xml file (say GameSettings.xml), then you need to use a writer to create the file, not a reader.
Bottom line, try XmlWriter instead of XmlReader.
mwpeck
May 30th, 2008, 12:22 PM
How will I tell it what to write in the file or does it use the App.Config automatically?
Arjay
May 30th, 2008, 12:33 PM
The way this works in the Save() method of the GameSettings class is it uses the XmlSerializer to serialize the GameSettings instance. It does this with the help of the xml attributes with the GameSettings, Game, and Property classes.
What problem are you trying to solve?
mwpeck
May 30th, 2008, 12:37 PM
I tried copying the Save() method:
XmlWriterSettings xws = new XmlWriterSettings();
xws.Indent = true;
using (XmlWriter writer = XmlWriter.Create(fullConfigFile, xws))
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
serializer.Serialize(writer, this, ns);
}
And it says "Keyword 'this' is not valid in a static property, static method, or static field initializer." I have a feeling thats close to how I would create the file, but I dont know what to replace 'this' with.
Arjay
May 30th, 2008, 04:07 PM
I have a feeling thats close to how I would create the file, but I dont know what to replace 'this' with.What problem are you trying to solve? Please explain what you are trying to do in a general sense.
mwpeck
May 30th, 2008, 04:17 PM
I need the program to use the config file in a different directory instead of a config file whereever the program resides.....that way no matter where I run it from, it will always use a static directory so it doesnt lose settings when it moves directories......the application data directory to be exact.
I already have the path detected and what not, I just need it to recreate the <programName>.config in a specific directory, not where ever the program is.
Arjay
May 30th, 2008, 04:42 PM
Can't you just pass in the name of the file (and the full path) to the methods responsible for saving and loading the settings?
public void Save( string filePath )
{
XmlSerializer serializer = new XmlSerializer( typeof( GameSettings ) );
XmlWriterSettings xws = new XmlWriterSettings( );
xws.Indent = true;
using( XmlWriter writer = XmlWriter.Create( filePath, xws ) )
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces( );
ns.Add( "", "" );
serializer.Serialize( writer, this, ns );
}
}
public static GameSettings Create( string filePath )
{
XmlSerializer serializer = new XmlSerializer( typeof( GameSettings ) );
using( XmlReader reader = XmlReader.Create( filePath ) )
{
return ( GameSettings )serializer.Deserialize( reader );
}
}
Also, you probably want to rename this file from GameSettings.exe.config file to something else (like GameSettings.xml or GameSettings.Dat).
This naming convention implies it's the configuration file for the exe and located in the same folder as the exe.
You're probably running into trouble because the settings file doesn't exist the first time the program is run?
If that's the case, just modify the program to detect whether the file exists and then read it or create a new one. You can do this in the GameSettings.Create( ) method.
public static GameSettings Create( string filePath )
{
XmlSerializer serializer = new XmlSerializer( typeof( GameSettings ) );
FileInfo fi = new FileInfo( filePath );
if( fi.Exists )
{
using( XmlReader reader = XmlReader.Create( filePath ) )
{
return ( GameSettings )serializer.Deserialize( reader );
}
}
else
{
GameSettings gameSettings = new GameSettings( );
// Optional - save at this point to create the file on disk
// or wait until the user saves the file after changing
// the settings.
// If you uncomment the next line, the file will be created
// immediately.
// gameSettings.Save( filePath );
return gameSettings;
}
}
mwpeck
May 30th, 2008, 05:40 PM
You're probably running into trouble because the settings file doesn't exist the first time the program is run?
Thats exactly where I was having troubles....the problem I had was I couldnt call Save() without having a GameSettings object, I couldnt create an object without having the file there already. (didnt know I could use GameSettings without the .create to initialize an object)
That being said, I picked some pieces of code out of what you wrote and got it working how I wanted it to...thanks once again.
Arjay
May 30th, 2008, 06:21 PM
Didnt know I could use GameSettings without the .create to initialize an object.As you probably know, you can access the private GameSettings constructor from within the static Create method.
General comment:
I usually try to write classes with static factory methods because when I use the class in other code, I want the code to be as clean as possible. It's a style thing, but I don't like to see 'new' in code that uses a class.
For me, instead of instantiating the GameSetting class with new...
GameSettings gameSettings = new GameSettings( filePath );
...I would rather use the class factory.
GameSettings gameSettings = GameSettings.Create( filePath );
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.