CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12
  1. #1
    Join Date
    Jun 2012
    Location
    .NET 4.0 / VS 2010
    Posts
    20

    Reading properties file

    Hello,

    I'm trying to read a txt file that has properties laid out in the format:
    Code:
    Info()
    {
    	Texture("textureName");
    	Angle(-90.000000);
    	Ambient(255.000000, 255.000000, 255.000000); //rgb
    	Filter(1);
    	Threshold(150);	
    	Intensity(50);
    
    	Softness(1);
    	SoftnessParam(60);
    
    	Model()
    	{	
    		Geometry("meshName");
    	}
    
    
    }
    That's a part of it, at least; just property values inside parentheses and curly brackets, as strings, doubles, and ints. The trouble is, StreamReader can't recognize what's inside the parentheses as values. Google gave me some tips on how to read ini files, which just use = to sepearte variables from values, but these property files are different in that they have values inside parentheses and a few properties [Ambient(r,g,b) for example] have three values associated with them.

    What makes it even more complicated is that I can't tell for sure what line any particular property will be at in the file.

    In other words, I can have float Angle in my program, and I can read Angle(-90.0); from the file, but how do I then assign a value of -90.0 to the Angle float?

  2. #2
    Join Date
    Nov 2011
    Posts
    36

    Re: Reading properties file

    That's a really odd property file. Have you written anything yet?

  3. #3
    Join Date
    Jun 2012
    Location
    .NET 4.0 / VS 2010
    Posts
    20

    Re: Reading properties file

    If by anything you mean code for reading it, I was trying to think of how to go about it when a friend suggested I use ReadLine to put each line into a string array, then for every property I could loop through the array until the first few characters of a line match that property's name. Once I got the property's position in the array I could use array[index].Substring(#, #) to get the value, and Convert.ToInt or something to convert it to a numeric value. Could that work?

    To do that for every single property (I'm expecting 10 - 60 properties per file) seems rather complex and expensive, but as you noted, it's a really odd file, so I'll have to do whatever works. To that end I wrote up some code to test it:
    Code:
    string fileName;
    string[] fileDataArray;
    int fDAIndex = 0;
    
            private void loadToolStripMenuItem_Click(object sender, EventArgs e)
            {
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    fileName = openFileDialog1.FileName;
    
                    System.IO.StreamReader tr = new System.IO.StreamReader(fileName);
                    // Read the lines of the file into an array
                    while (tr.Peek() >= 0)
                    {
                        fileDataArray[fDAIndex] = tr.ReadLine();
                        fDAIndex = fDAIndex + 1;
                    }
                    tr.Close();
    
                    fDAIndex = 0;
                    // Get the index where the string containing "Angle(-90.0);" is stored
                    while (fileDataArray[fDAIndex].Substring(0, 5) != "Angle")
                    {
                        fDAIndex = fDAIndex + 1;
                    }
                    // Get the "-90.0" part of the string
                    string angleValueStr = fileDataArray[fDAIndex].Substring(5, 5);
                    // To check if it worked, display angleValueStr in the angleValueText textbox (already on the form)
                    angleValueText.Text = angleValueStr;
                }
            }
    When I load the file, I get an error at fileDataArray[fDAIndex] = tr.ReadLine(); saying that "NullReferenceException was unhandled" and "Object reference not set to an instance of an object." What's going on? Moreover, is there a better way to get this data than this current playing around with ReadLine and string array and substrings?


    EDIT - I changed the code slightly. Instead of that bit with the tr StreamReader and the while loop that loads the lines into an array, I now just have the one line:
    Code:
    fileDataArray = System.IO.File.ReadAllLines(fileName);
    I still get an error when loading the file, this time at the line that says
    Code:
    while (fileDataArray[fDAIndex].Substring(0, 5) != "Angle")
    The error is "Index and length must refer to a location within the string." The problem is with Substring(0, 5); some lines only have one character, so I get an error when Substring tries to read the first 5 characters. How to I get the while loop to continue on past that error? I can't really do Substring(0, 1) since 1 character isn't really much use in identifying the property.

    Further, even when I used Substring(0, 1) != "A", I got the same error. I guess C# reads the lines with just newline characters as characterless, so it will only accept Substring(0, 0)?
    Last edited by fiodis; June 27th, 2012 at 06:19 PM.

  4. #4
    Join Date
    Nov 2011
    Posts
    36

    Re: Reading properties file

    I personally do not like ReadAllLines as it can get very memory intensive but if the files are small I guess it doesn't really matter.

    To fix your substring issue you can use:

    Code:
    while (fileDataArray[fDAIndex].Substring(0, fileDataArray[fDAIndex].IndexOf("(")) != "Angle")
    
    //for the properties value
    fileDataArray[fDAIndex].Substring(fileDataArray[fDAIndex].IndexOf("(") + 1)
    The problem is when you were doing Sustring(0, 5) and you only have a string that may be 4 characters long, you will hit the exception you are currently having problems with.
    So what I do is get the index of the "(" parentheses symbol + 1, then I do not need a length, it will just take that index to the end of the string. If you need to cut white space add .Trim()

    **Also Note**
    I am not on my work computer lmao, so I may have spelled something wrong or missed a character/symbol cause I am lazy and always check with VS haha
    Last edited by Deranged; June 27th, 2012 at 07:49 PM.

  5. #5
    Join Date
    Nov 2011
    Posts
    36

    Re: Reading properties file

    Oh yea, duh, forgot there is a ")" at the end lol
    In that case, couple ways to deal with this.

    Code:
    //for the properties value
    int num = 0;
    
    fileDataArray[fDAIndex].Substring(num = fileDataArray[fDAIndex].IndexOf("(") + 1, fileDataArray[fDAIndex].IndexOf(")") - num
    or you can remove it by getting the length of line..

    Code:
    //for properties value
    int length = 0;
    
    length = yourstring.Length()
    
    fileDataArray[fDAIndex].Substring(fileDataArray[fDAIndex].IndexOf("(") + 1).Remove(length - 1)
    It's something along those lines, ugh... I feel terrible without IDE/Intellisense.... Feel bad for old programmers

    *Edit*
    Come to think of it, you probably can't use length on an array. Length will return the array index basically. Sigh
    Last edited by Deranged; June 27th, 2012 at 07:51 PM.

  6. #6
    Join Date
    Jun 2012
    Location
    .NET 4.0 / VS 2010
    Posts
    20

    Re: Reading properties file

    Wow, I didn't know about IndexOf; that'll be useful.

    Unfortunately I get an error inside the while loop, again with the length parameter of Substring, this time saying that "Length cannot be less than zero." I'm guessing that for lines without a "(" char the IndexOf("(") evaluates to -1 or something. The trouble is I can't do IndexOf("(") + 1 inside the while loop since that will include the first character of the actual property value, and I won't be able to check that against the property name inside the while condition.

    Is there some way I can tell the program, "If you encounter this error, no biggie, just ignore it and execute the while loop anyway"? Or maybe a better way would not use a while statement at all? It's getting late now, but in the morning I think I'll try something with a try-catch statement. I've never used those before but they seem like they handle errors better than what the code's currently using.

  7. #7
    Join Date
    Nov 2011
    Posts
    36

    Re: Reading properties file

    I'm just going to install VS2010 lol... give me an hour or so I'll reply back with something you can work with.

  8. #8
    Join Date
    Nov 2011
    Posts
    36

    Re: Reading properties file

    Ok so I wrote this up extremely fast, but this is an idea of how I would read the file. If I had your source or knew exactly how you specify the property or what you want to do with it I'd be able to help further but here you go:

    Code:
    namespace ReadPropertyFile
    {
        class Program
        {
            static void Main(string[] args)
            {
                string fn = @"C:\Users\Kelby\Documents\Visual Studio 2010\Projects\ReadPropertyFile\Properties.txt";            
    
                foreach (List<string> propData in RetrievePropertyData(fn))
                {
                    string formattedPropData = String.Format("\nProperty Name: {0}\nProperty Value: {1}", propData[0], propData[1]);
    
                    Console.Write(formattedPropData);
                    Console.ReadKey();
                }
            }
    
            private static IEnumerable<List<string>> RetrievePropertyData(string fileName)
            {
                List<string> ret = new List<string>();
                string line = string.Empty;
                int num = 0;
    
                using (StreamReader sr = new StreamReader(fileName))
                {
                    while (!sr.EndOfStream)
                    {
                        line = sr.ReadLine().Trim();
    
                        if (line.Trim().Length <= 1) continue; //Those stupid "}{" are evil
                        if (ret.Count > 1) ret = new List<string>();
    
                        ret.Add(line.Substring(0, line.IndexOf("(")));
    
                        if (IsQualifiedOrMultiValued(line))
                            line = line.Replace("\"", "");
    
                        ret.Add(line.Substring(num = line.IndexOf("(") + 1, line.IndexOf(")") - num));
    
                        
    
                        yield return ret;
                    }
                }
            }
    
            private static bool IsQualifiedOrMultiValued(string inputLine)
            {
                for (int i = 0; i < inputLine.Length; i++)
                {
                    if (inputLine[i] == '"')
                        return true;
                }
                return false;
            }
        }
    }

  9. #9
    Join Date
    Jun 2012
    Location
    .NET 4.0 / VS 2010
    Posts
    20

    Re: Reading properties file

    Thanks! I was messing around with try/catch, but that code loads it perfectly (though newline in C# is \r\n instead of \n )

    I'm not quite sure how lists work, though I think I have a basic understanding from this article. What is the purpose of putting
    Code:
    if (ret.Count > 1) ret = new List<string>();
    inside the while loop? It looks like it sets ret to a clean, new list every time it gets more than 1 element.

  10. #10
    Join Date
    Nov 2011
    Posts
    36

    Re: Reading properties file

    I was only using \n for console testing, doesn't really matter. I would personally use Environment.Newline for cross platform.

    I was renewing the list because I didn't want to read all the properties straight into the list. Because in my console testing I was using propData[0] and propData[1] so I was only expecting the property name and property value. Of course if I want to just read all the properties into the list, just remove the renewing of the list and use a for loop or something to indicate the index within the list.

    Like I said, I didn't really know what end result you were looking for? I could have added it to a form so you could be like "I want to know this property" so then you pass the argument into the parser, looks for that property and then displays result? I just simply read them all and displayed their value.

  11. #11
    Join Date
    Jun 2012
    Location
    .NET 4.0 / VS 2010
    Posts
    20

    Re: Reading properties file

    Ah, I see. Again, thanks for the help, and thanks for the tip about Environment.Newline.

  12. #12
    Join Date
    Nov 2011
    Posts
    36

    Re: Reading properties file

    Absolutely! If you need any more help feel free to ask.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured