user2619395
user2619395

Reputation: 249

C# How go through a text file to find a specific value

I was trying to figure out how to go through a text file where the contents are formatted like this:

Date: 7/30/2013 12:00:00 AM 
Source Path: C:\FileMoveResults 
Destination Path: C:\Users\Documents\.NET Development\testing\ 
Last Folder Updated: 11.0.25.1

Where I could search it depending on the "Last Folder Updated" and store the source path and destination path in seperate variables.

How would one go about doing this?

Thanks!

Edit:

Here is the code I currently have which doesnt work since i'm getting the error that "foreach doesn't support bool"

using (var reader = new StreamReader(GlobalVars.strLogPath))
{
foreach (var items in File.ReadLines(GlobalVars.strLogPath))
{
foreach(var item in items.StartsWith("Destination Path: "))
{
//nothing here yet

Upvotes: 0

Views: 2971

Answers (4)

Cubicle.Jockey
Cubicle.Jockey

Reputation: 3328

Here is a sample starter for how to do it with LINQ. I used LinqPad to play with the code.

    var input = "Date: 7/30/2013 12:00:00 AM\nSource Path: C:\\FileMoveResults\nDestination Path: C:\\Users\\Documents\\.NET Development\\testing\\ \nLast Folder Updated: 11.0.25.1 \nDate: 7/30/2013 12:00:00 AM\nSource Path: C:\\FileMoveResults\nDestination Path: C:\\Users\\Documents\\.NET Development\\testing\\ \nLast Folder Updated: 11.0.25.1 \nDate: 7/30/2013 12:00:00 AM\nSource Path: C:\\FileMoveResults\nDestination Path: C:\\Users\\Documents\\.NET Development\\testing\\ \nLast Folder Updated: 11.0.25.1 \nDate: 7/30/2013 12:00:00 AM\nSource Path: C:\\FileMoveResults\nDestination Path: C:\\Users\\Documents\\.NET Development\\testing\\ \nLast Folder Updated: 11.0.25.1 \nDate: 7/30/2013 12:00:00 AM\nSource Path: C:\\FileMoveResults\nDestination Path: C:\\Users\\Documents\\.NET Development\\testing\\ \nLast Folder Updated: 11.0.25.1 \nDate: 7/30/2013 12:00:00 AM\nSource Path: C:\\FileMoveResults\nDestination Path: C:\\Users\\Documents\\.NET Development\\testing\\ \nLast Folder Updated: 11.0.25.1 \nDate: 7/30/2013 12:00:00 AM\nSource Path: C:\\FileMoveResults\nDestination Path: C:\\Users\\Documents\\.NET Development\\testing\\ \nLast Folder Updated: 11.0.25.1 \nDate: 7/30/2013 12:00:00 AM\nSource Path: C:\\FileMoveResults\nDestination Path: C:\\Users\\Documents\\.NET Development\\testing\\ \nLast Folder Updated: 11.0.25.1 \nDate: 7/30/2013 12:00:00 AM\nSource Path: C:\\FileMoveResults\nDestination Path: C:\\Users\\Documents\\.NET Development\\testing\\ \nLast Folder Updated: 11.0.25.1";

string[] lines = null;
using(var reader = new StreamReader(new MemoryStream(Encoding.ASCII.GetBytes(input))))
{
    lines = reader.ReadToEnd().Split('\n');
}

IList<Tuple<string, string>> paths = new List<Tuple<string, string>>();
if(lines != null)
{
    const int TAKE = 4;

    var position = 0;

    while(position < lines.Length)
    {
        var currentLines = lines.Skip(position).Take(TAKE);
        paths.Add(Tuple.Create(currentLines.ElementAt(1).Replace("Source Path: ", string.Empty), currentLines.ElementAt(2).Replace("Destination Path: ", string.Empty)));
        position = (position + TAKE);
    }
}

paths.Dump("Result");

What I did was gather all of the source and destination paths. You can modifiy this to only store the ones you want based on your search criteria.

Result looks like this, granted I just copied your example over and over so there is no variation in path names:

enter image description here

I would probably also make the Tuple of type Tuple<DictionaryInfo, DictionaryInfo> if you want to have move and copy abilities built into your objects.

Upvotes: 0

Khan
Khan

Reputation: 18142

Heres an example of how it can be done. There is plenty of room for improvement here in the areas of handling badly formatted lines etc..

    static void ReadFile(string path)
    {
        var lines = System.IO.File.ReadAllLines(path).ToList();
        var infos = new List<TextFileInfo>();

        var info = new TextFileInfo();
        var currentLine = 0;
        while (lines.Count > 0)
        {
            TryReadLine(lines[0], info);

            if (currentLine++ >= 3)
            {
                currentLine = 0;
                infos.Add(info);
                info = new TextFileInfo();
            }

            lines.RemoveAt(0);
        }

        //Do something with infos
        // return infos;
   }

    public static void TryReadLine(string line, TextFileInfo info)
    {
        if (line.StartsWith(DateTag))
        {
            var value = line.Replace(DateTag, string.Empty).Trim();
            info.Date = DateTime.Parse(value);

            return;
        }

        if (line.StartsWith(SourcePathTag))
        {
            var value = line.Replace(SourcePathTag, string.Empty).Trim();
            info.SourcePath = value;

            return;
        }

        if (line.StartsWith(DestinationPathTag))
        {
            var value = line.Replace(SourcePathTag, string.Empty).Trim();
            info.DestinationPath = value;

            return;
        }

        if (line.StartsWith(LastFolderUpdatedTag))
        {
            var value = line.Replace(SourcePathTag, string.Empty).Trim();
            info.LastFolderUpdated = value;

            return;
        }

        throw new Exception("Invalid line encountered");
    }

    public class TextFileInfo
    {
        public DateTime Date { get; set; }
        public string SourcePath { get; set; }
        public string DestinationPath { get; set; }
        public string LastFolderUpdated { get; set; }
    }

Upvotes: 0

tsells
tsells

Reputation: 2771

I was thinking something like this. It's a little more complicated but will help ensure if your file's format changes you should still be able to loop through and find each set of values.

    public void ReadFile(string filepath)
    {
        Dictionary<string, string> mypaths = new Dictionary<string, string>();
        string line;
        string line1 = null;
        string line2 = null;
        bool store = false;
        using(var rdr = new StreamReader(filepath))
        {
            while((line = rdr.ReadLine()) != null)
            {
                if(store = false && line.ToLower().Contains("source path:"))
                {
                    line1 = line;
                    store = true;
                }
                else if (store = true && line.ToLower().Contains("destination path:"))
                {
                    line2 = line;
                }
                else if (line.ToLower().Contains("last folder updated:"))
                {
                    var myvaluetoinspect = line;
                    if(1==1) // my condition
                    {
                        mypaths.Add(line1, line2);
                    }
                    // Clear and start over
                    store = false;
                    line1 = null;
                    line2 = null;
                }
                else
                {
                    store = false;
                    line1 = null;
                    line2 = null;
                }
            }
        }
    }

Upvotes: 0

D.R.
D.R.

Reputation: 21194

  • Read 4 lines a time
  • Parse the last line (last folder updated)
  • Check if you want to store the entry
  • If yes -> store line 2 and line 3
  • Repeat until no more lines available

Edit: Reflecting your new question about your code:

Remove the innermost foreach loop and rename "items" to "oneSingleLine" - this should make it more clear where your error resides. Maybe create a new question as this is not a discussion board.

Upvotes: 4

Related Questions