Jump to content

A few questions about different things (C#)


Recommended Posts

I'm working on a few different projects right now and I have a few questions about how to do some things.

 

First, I'm making a program that will have some user input: an Xbox Live gamertag and a save location.  I want to save this information to an ini file in the same directory as the program executable, but I need to know the best way to read and write an ini config file.  A google search returns some results but they all seem kinda complicated, is there just a REALLY simple way to open and access the values from an ini file?  I'm pretty sure I'll only need to set those 2 values.

 

Second, what is the best way to parse an XML file retrieved from the internet?  I used an httprequest and a streamreader to get the file and return it into a multi-line textbox so I can confirm that it got the file, but I was reading a C# book and saw that there was a method, XmlReader(), that can accept a URL as the parameter, should I do it that way?  I need at least 2 pieces of information from each <item> in the file, but most likely I'll want to pull 4 pieces of information: the title, pubdate, and 2 URL's.  I was reading, in the same book, about XmlNodeType, so I could do something like this:

 

string url = "[the url to retrieve]";
XmlReader reader = new XmlReader(url);
while(reader.Read())
{
    if(reader.XmlNodeType [...]) //something
    {
        [...] //blah blah blah
    }
}

 

And to get the name and value I'd use reader.Name and reader.Value, right?  But I also read about ReadElementString(), so to be honest I don't know which to use, which is going to get what I want in the best, fastest, most efficient way.  In total there should be 30 <item>'s per XML file, so at 4 pieces of info per <item> and 30 <item>'s, I'll be getting 120 pieces of information.  It needs to be fast.

 

And finally, I'll need to download the information found at one of those URL's I'm pulling from the XML file and save it to a temporary directory.  It's a thumbnail image that I want to use a reference to the full-size image the person will be downloading (using the program.)  For this would I simply create a method that accepts a URL as the parameter and downloads the data and saves it to a temp directory?  The images are always jpg, and I want the temp images deleted when the program closes.

 

So I know that I'm asking a lot from you guys, but any help with any of these subjects will be most appreciated!  Thanks in advance, ya'll are the best!

Link to comment
Share on other sites

I don't believe .NET has a built in class for reading ini files, I believe it's recommended to generally use xml files in place of ini files. But there are plenty of free classes around to read ini files using interop (like this for example).

 

It's a long time since I've worked with XML, I worked with it fairly extensively on the Compact Framework 1.1 but that was about 5 years ago and I've forgotten most of what I learned at the time. From what I remember the two options available to me at the time were the XmlReader which sequentially reads through the file and XmlDocument, which loads it into a DOM. From a performance point of view XmlReader was alot faster especially when working with large files. The size of file your talking about is pretty tiny in comparison, but I'd suggest XmlReader would still be the faster of the two.

 

From what I remember the most common elements of the class I used were .Name, .Value and .GetAttributes.

Link to comment
Share on other sites

I don't believe .NET has a built in class for reading ini files, I believe it's recommended to generally use xml files in place of ini files. But there are plenty of free classes around to read ini files using interop (like this for example).

 

It's a long time since I've worked with XML, I worked with it fairly extensively on the Compact Framework 1.1 but that was about 5 years ago and I've forgotten most of what I learned at the time. From what I remember the two options available to me at the time were the XmlReader which sequentially reads through the file and XmlDocument, which loads it into a DOM. From a performance point of view XmlReader was alot faster especially when working with large files. The size of file your talking about is pretty tiny in comparison, but I'd suggest XmlReader would still be the faster of the two.

 

From what I remember the most common elements of the class I used were .Name, .Value and .GetAttributes.

 

From what I understand, a lot of .NET XML work is now done with LINQ-to-XML (XLINQ).  I've played with retrieving data from an XML file and populating objects with that data through XLINQ, and it's pretty nice.  It feels a lot like vanilla SQL, so it's pretty natural to write.  Example (rough, since it's still a work in process):

 

protected void Page_Load(object sender, EventArgs e)
{
    List<Attack> charAttacks = (from a in XElement.Load(MapPath("CharacterClasses/Hacker.xml")).Element("Attacks").Elements("Attack")
                                let se = a.Element("StatusEffect")
                                select new Attack
                                (
                                    (string)a.Element("AttackName"),
                                    (int)a.Element("AttackLevel"),
                                    (int)a.Element("TPCost"),
                                    (double)a.Element("DMGModifier"),
                                    (double)a.Element("HitPenalty"),
                                    CreateStatusEffect(se)
                                )).ToList();
}

public StatusEffect CreateStatusEffect(XElement se)
{
    if (se.Element("Type") != null)
    {
        StatusEffect result = (StatusEffect)Assembly.GetExecutingAssembly().CreateInstance(((string)se.Element("Type")));
        result.Name = (string)se.Element("Name");
        result.Duration = (int)se.Element("Duration");
        result.Level = (int)se.Element("Level");

        return result;
    }
    else
    {
        throw new Exception();
    }
}

 

My XML file is:

 

<?xml version="1.0" encoding="utf-8" ?>
<CharacterClass>
  <Name>Hacker</Name>
  <InitialStats>
    <HP>10</HP>
    <TP>25</TP>
    <BaseDMG>2</BaseDMG>
    <BaseDefense>25</BaseDefense>
  </InitialStats>
  <LevelingStats>
    <HPMultiplier>2</HPMultiplier>
    <TPMultiplier>4</TPMultiplier>
    <BaseDMGMultiplier>2</BaseDMGMultiplier>
    <DefenseIncrease>5</DefenseIncrease>
  </LevelingStats>
  <Attacks>
    <Attack>
      <AttackName>Basic Attack</AttackName>
      <AttackLevel>1</AttackLevel>
      <TPCost>0</TPCost>
      <DMGModifier>1</DMGModifier>
      <HitPenalty>0</HitPenalty>
      <StatusEffect>
        <Type>null</Type>
        <Duration>0</Duration>
        <Level>0</Level>
      </StatusEffect>
    </Attack>
  </Attacks>
</CharacterClass>

 

So, the code loads the Hacker.xml file into memory, and performs a select query on each Attack element.  It then builds a new Attack object from that returned data, and stuffs it in the List.

 

The hardest part was getting a hold of the embedded Status Effect info.  Those, too, are objects, because they are applied both through attacks and items.  I'm still trying to figure out how to handle those attacks and items that shouldn't have Status Effects, but that's not really important for this topic.

Link to comment
Share on other sites

Ok, thanks corbin and nightslyr, I'll look into both of those methods.

 

One more thing though, this stupid project keeps throwing problem after problem at me!  I'm trying to run one method on it's own thread.  I've got threading turned on "using System.Threading;" and I'm using this code:

 

private void blf_converter(object fileName)
        {
            string filename = fileName.ToString();
            // [...]
            textBox1.Text += "Opening File " + filename + "..." + Environment.NewLine; // This is my problem!
            // [...]
            }
        }

private void batchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            fbd.Description = "Please select the folder where your .blf images are located:";
            fbd.ShowNewFolderButton = false;
            if (fbd.ShowDialog() == DialogResult.OK)
            {
                DirectoryInfo batch = new DirectoryInfo(fbd.SelectedPath);
                FileInfo[] files = batch.GetFiles("*.blf");
                progressBar1.Maximum = files.Length;
                textBox1.Clear();
                foreach (FileInfo file in files)
                {
                    //Thread t = new Thread(blf_converter);
                    //t.Start(file.FullName);
                    //ThreadPool.QueueUserWorkItem(blf_converter, file.FullName);
                    progressBar1.PerformStep();
                }
            }
        }

 

I get an error in blf_converter that reads this:

 

InvalidOperationException was unhandled

Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on.

 

I'm trying to write something to textBox1 but it won't let me because it was created on a different thread than the one running blf_converter().  Is there anything I can do to make this work?  I'd like for the new line to be written to the textbox for every file that's processed, as it's processed, not as one big block of text after the processing.

 

Sorry I'm heaping so much on you guys, but google isn't coming up with anything here.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.