Разбор странно отформатированных файлов - PullRequest
0 голосов
/ 29 мая 2009

Мне нужно проанализировать файл, но данные находятся в странном формате, который я не использую для семейного анализа.

Данные всегда форматируются следующим образом. Имя поля слева, а данные справа от "=", и все поля всегда в этом порядке.

Данные файла:

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

Мой первый инстинкт - делать что-то вроде этого ...

        '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

Это не кажется мне очень чистым или элегантным.

Есть ли более элегантный способ обработки таких файлов?

Ответы [ 3 ]

1 голос
/ 29 мая 2009

Следующий код - C #, но его легко перевести на VB. Он использует словарь для сопоставления ключа из файла с PropertyInfo, а затем устанавливает значение, используя отражение. Обработка первой строки отсутствует и, возможно, есть еще некоторые незначительные проблемы.

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);
    }
}
0 голосов
/ 29 мая 2009

Это C # (извините, я не получил VB) и не имеет никакой проверки ошибок, но как насчет чего-то вроде ListValuePairs ...

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();
        }
    }
}
0 голосов
/ 29 мая 2009

Скорее всего, я прочитал бы каждую строку, разделил ее на = и поместил бы в строковый хеш, где имя поля - это ключ, чтобы вы могли ссылаться на него по имени поля.

...