0

I have a log file that i want to present in a DataGridView.

An Example line of data in the file would be :-

<![LOG[Creating mandatory request for advert 0002124C, program Shutdown Desktops Overnight, package 0000073C]LOG]!><time="05:00:00.192+000" date="02-11-2013" component="execmgr" context="" type="1" thread="3712" file="execreqmgr.cpp:2858">

I want to pull out aspects of the example above, Log Description, Time & Date, component, context, type and Thread.. and add them as columns in the DataGridView's DataSource.

Which is the best way to tackle pulling this data out?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Derek
  • 8,300
  • 12
  • 56
  • 88
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Feb 19 '13 at 14:33
  • Are the values in the Log File comma separated ? if so , split the values into a List and Bind that List to the datagridview or read the values into a dataset or datatable and bind them that way.. – MethodMan Feb 19 '13 at 14:34
  • There not comma seperated mate, its exactly as I've posted above. That is one line in the file. It makes it more awkward, not sure how to approach it. – Derek Feb 19 '13 at 14:36

1 Answers1

0

I would suggest DJ Kraze's approach: creating a custom list and binding it to your DataGridView. Just use custom code to parse the line. You may use a DataTable, too, if you have to, however the List approach is usually cleaner.

Something like (I didn't check the exact syntax or method calls, so use as an example only, you will need a text reader, for example):

public class LogEntry {
   public string Description { get; set; }
   public DateTime LogDate { get; set; }
   // other properties you want to extract
}

public class LogReader {
   public List<LogEntry> ReadLog(string fileName){
       var parsedLog = new List<LogEntry>();
       using(var file = File.Open(filename, ....)){
           while(var line = file.ReadLine()){
               var logEntry = ParseLine(line);
               parsedLog.Add(logEntry);
           }
       }
       return parsedLog;
   }

   private LogEntry ParseLine(string line){
       var logEntry = new LogEntry();
       // go through the line and parse it with string functions and populate values.
       // I use a helper class, a shortened version is below - note, you might need to
      //adjust to compile
       var parser = new StringParser(line);
       //now just use GetBetween to find the values you need. just pick your delimiters
       // carefully as the parser will move beyond the end string.  But it will go
       // sequentially so just experiment
      logEntry.Description = parser.GetBetween("LOG[", "]LOG");
      // go through in order
   } 
}

public class StringParser {
    private string text;
    private int position;

    public StringParser(string text)
    {
        this.Text = text;
    }  

    public string Text
    {
        get { return this.text; }
        private set
        {
            this.text = value;
            Position = 0;
        }
    }

    public int Position
    {
        get { return this.position; }
        private set
        {
            if (value < 0)
            {
                this.position = 0;
            }
            else
            {
                this.position = value > this.Text.Length ? this.Text.Length : value;
            }
        }
    }

    public bool AtEnd
    {
        get { return this.Position >= this.Text.Length; }
    }

    public string GetBetween(string beforeText, string afterText)
    {
        var startPos = MoveAfter(beforeText);
        if (startPos == -1)
        {
            return "";
        }

        var endPos = FindNext(afterText);
        return GetBetween(startPos, endPos);
    }

     public string PeekBetween(int startPos, int endPos)
    {
        if (startPos < 0 || startPos >= this.text.Length)
        {
            return "";
        } 
        if (endPos < 0 || endPos > this.text.Length)
        {
            endPos = this.text.Length;
        } 
        if (startPos >= endPos)
        {
            return "";
        }

        var result = this.text.Substring(startPos, endPos - startPos);
        return result;
    }

    public string GetBetween(int startPos, int endPos)
    {
        if (endPos < 0 || endPos > this.text.Length)
        {
            endPos = this.text.Length;
        } 
        var result = PeekBetween(startPos, endPos);
        if (!string.IsNullOrEmpty(result))
        {
            this.Position = endPos;
        }
        return result;
    }


    public int FindNext(string searchText)
    {
        if (string.IsNullOrEmpty(searchText) || this.AtEnd)
        {
            return -1;
        } 
        return this.text.IndexOf(searchText, this.Position, StringComparison.Ordinal);
    }   

    public int MoveAfter(string searchText)
    {
        var found = FindNext(searchText);
        if (found > -1)
        {
            found += searchText.Length;
            this.Position = found;
        }
        return found;
    } 
}
gabnaim
  • 1,103
  • 9
  • 13
  • Thanks for this, Its the parsing part I'm struggling with – Derek Feb 19 '13 at 15:34
  • I added a shortened version of the StringParser class I use as an example. You might need to adjust it, however you generally can get an idea of how to use string functions from it. – gabnaim Feb 19 '13 at 15:58
  • I was adding the parts that were missing. Basically you are using the string functions IndexOf() to find start and end positions, and then use Substring() to get the string between. – gabnaim Feb 19 '13 at 16:03