views:

115

answers:

3

I need to parse a file but the data is in a strange format that I'm not familar parsing.

The data is always formatted like this. The field name is to the left and the data is right of the "=" and all fields are always in this order.

File Data:

Report 1 of 1 
job_name = JOBNAME
job_no = JOB99999 job_id = 6750
rprt_id = 27811
rprt_name = SOMEDATA.SOMEUSER.JOBNAME.JOB099999.0000000.?
ftp_size = 999999 
job_group_name = 1
clas = Z
form = 9999 
user_id = SOMEUSER

My first instinct is to do something like this...

        'New up a class created to hold the data'
        Dim NFOData As New NFOData
        'Create counter for line numbers'
        Dim i As Integer = 1

        Using sr As New StreamReader(filename)
            While Not sr.EndOfStream
                Dim line As String = sr.ReadLine

                Select Case i
                    Case 2
                        NFOData.JobName = line.Substring(11)
                    Case 3
                        NFOData.JobNo = line.Substring(9)
                    Case 4
                        'snipped to save space'
                End Select

                i += 1
            End While
        End Using

This doesn't seem very clean or elegant to me.

Is there a more elegant way to handle parsing files like this?

A: 

I would likely read each line, split it on the =, and put it in a string hash where field name is the key so you can then reference it by fieldname.

RedFilter
A: 

This is C# (sorry, I got no VB) and has no error checking of any kind, but how about something like a List of KeyValuePairs ...

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace NVP
{
    class Program
    {
        static void Main(string[] args)
        {
            var nvp = new List<KeyValuePair<string, string>>();
            var fs = File.Open(@"c:\temp\report.txt", FileMode.Open);

            var sw = new StreamReader(fs);

            while (!sw.EndOfStream)
            {
                var line = sw.ReadLine();
                if (!String.IsNullOrEmpty(line) && line.Contains("="))
                {
                    var tmp = line.Split('=');
                    nvp.Add( new KeyValuePair<string, string>(tmp[0], tmp[1]));
                }
            }

            sw.Close();
            fs.Close();

            var str = nvp.Select(kv => kv.Key + " " + kv.Value);
            str.ToList().ForEach(Console.WriteLine);

            Console.ReadLine();
        }
    }
}
JP Alioto
+1  A: 

The following code is C# but should easily translate to VB. It uses a dictionary to map the key from the file to a PropertyInfo and then sets the value using reflection. Handling of the first line is missing and maybe there are some more minor issues.

Dictionary<String, PropertyInfo> map = new Dictionary<String, PropertyInfo>();

map["job_name"] = typeof(NFOData).GetProperty("JobName");
map["job_no"] = typeof(NFOData).GetProperty("JobNo");
// ....

NFOData nfoData = new NfOData();

using (StreamReader sr = new StreamReader(filename))
{
    String line;

    while ((line = sr.ReadLine()) != null)
    {
        String[] parts = line.Split(new[] {" = "}, StringSplitOptions.None);

        map[parts[0]].SetValue(nfoData, parts[1], null);
    }
}
Daniel Brückner