tags:

views:

326

answers:

3

I Have a text file that is like the following:

[group1] value1 value2 value3

[group2] value1 value2

[group3] value3 value 4

etc

What I want to be able to do, is load the values into an array (or list?) based on a passed in group value. eg. If i pass in "group2", then it would return a list of "value1" and "value2".

Also these values don't change that often (maybe every 6 months or so), so is there a better way to store them instead of a plain old text file so that it makes it faster to load etc?

Thanks for your help.

Leddo

+1  A: 

This is a home work question?

Use the StreamReader class to read the file (you will need to probably use .EndOfStream and ReadLine()) and use the String class for the string manipulation (probably .StartsWith(), .Substring() and .Split().

As for the better way to store them "IT DEPENDS". How many groups will you have, how many values will there be, how often is the data accessed, etc. It's possible that the original wording of the question will give us a better clue about what they were after hear.

Addition:

So, assuming this program/service is up and running all day, and that the file isn't very large, then you probably want to read the file just once into a Dictionary(of String, List(of String)). The ContainsKey method of this will determine if a group exists.

   Function GetValueSet(ByVal filename As String) As Dictionary(Of String, List(Of String))
        Dim valueSet = New Dictionary(Of String, List(Of String))()
        Dim lines = System.IO.File.ReadAllLines(filename)
        Dim header As String
        Dim values As List(Of String) = Nothing
        For Each line As String In lines
            If line.StartsWith("[") Then
                If Not values Is Nothing Then
                    valueSet.add(header, values)
                End If
                header = GetHeader(line)
                values = New List(Of String)()
            ElseIf Not values Is Nothing Then
                Dim value As String = line.Trim()
                If value <> "" Then
                    values.Add(value)
                End If
            End If
        Next
        If Not values Is Nothing Then
            valueSet.add(header, values)
        End If
        Return valueSet
    End Function

    Function GetHeader(ByVal line As String)
        Dim index As Integer = line.IndexOf("]")
        Return line.Substring(1, index - 1)
    End Function

Addition:

Now if your running a multi-threaded solution (that includes all ASP.Net solutions) then you either want to make sure you do this at the application start up (for ASP.Net that's in Global.asax, I think it's ApplicationStart or OnStart or something), or you will need locking. WinForms and Services are by default not multi-threaded.

Also, if the file changes you need to restart the app/service/web-site or you will need to add a file watcher to reload the data (and then multi-threading will need locking because this is not longer confined to application startup).

Swanny
+1 for it depends, I think we need an `it-depends` tag, much more useful than `subjective` http://meta.stackoverflow.com/questions/19113/do-we-really-need-the-subjective-tag-and-is-it-commonly-mis-used/21941#21941
MarkJ
Hi, Not actually a homework question, just something from a newbie to .NET...I'll explain what i'm trying to do:I have an external application,that I have no control over, that will pass me a Group Value (eg "Group 1"). I need to return back a collection of items that will be added to a drop down list. These items are stored in that text file that I mentioned. This routine would be called about 8,000 times per day, so I want to make is as efficient as possible. Also, the values don't change frequently so i'm thinking if there was some way to load them up as part of the app config.
Leddo
A: 

ok, here is what I edned up coding:

   Public Function FillFromFile(ByVal vFileName As String, ByVal vGroupName As String) As List(Of String)
        ' open the file
        ' read the entire file into memory
        ' find the starting group name
        Dim blnFoundHeading As Boolean = False
        Dim lstValues As New List(Of String)

        Dim lines() As String = IO.File.ReadAllLines(vFileName)
        For Each line As String In lines
            If line.ToLower.Contains("[" & vGroupName.ToLower & "]") Then
                ' found the heading, now start loading the lines into the list until the next heading
                blnFoundHeading = True
            ElseIf line.Contains("[") Then
                If blnFoundHeading Then
                    ' we are at the end so exit the loop
                    Exit For
                Else
                    ' its another group so keep going

                End If
            Else
                If blnFoundHeading And line.Trim.Length > 0 Then
                    lstValues.Add(line.Trim)
                End If
            End If
        Next

        Return lstValues

    End Function
Leddo
From your original post I got the impression that all values for a group were on the same line as the heading.
Swanny
A: 

Regarding a possible better way to store the data: you might find XML useful. It is ridiculously easy to read XML data into a DataTable object.

Example:

Dim dtTest                        As New System.Data.DataTable
dtTest.ReadXml("YourFilePathNameGoesHere.xml")
Matthew J Sullivan