-1

I have a C# WPF application where I save logs as a text file.

The log is saved as YYYY-MM-DD HH:MM LogContent format.

I was able to read the first line of the log file and compare the date to see if it is more than 2 weeks old using code below.

string filePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string logFileName = @"MyLog.log";

public void CleanupTimeLog()
{
    string getDate = File.ReadLines(filePath + logFileName).First();

    DateTime loggedTime = DateTime.Parse(getDate.Substring(0, 10));

    if (loggedTime.AddDays(13) < DateTime.Now.Date)
    {
        // delete the line
    }
}

Deleting multiple lines using foreach seems very inefficient. How do I achieve my goal the simplest way possible?

I have checked some examples of deleting lines from text files, but I still cannot figure out how to delete them by dates.

How to delete a line from a text file in C#?

Delete specific line from a text file?

Skysmith
  • 19
  • 5
  • 2
    Don't delete lines from the beginning of a file, write a new file containing only the lines you want. If you want to replace the old file with the new one then [use `File.Replace`](https://stackoverflow.com/questions/324670/). – Dour High Arch Nov 21 '19 at 23:42
  • 1
    The posts you linked provide fairly straightforward and consistent advice about how to remove lines (namely: writing to a new file with just the lines you want, and replacing the original file if necessary). What part of this problem, specifically, are you struggling to figure out? – StriplingWarrior Nov 21 '19 at 23:46
  • PS--have you looked into changing your logging configuration so you don't have to worry about this? Most logging frameworks make it easy to write to a new log file each day, and clean up log files after a certain period of time. – StriplingWarrior Nov 21 '19 at 23:48
  • I understood the concept of reading all lines from a text file, then keep only the lines I'd like to keep then replace the file. The posts I have linked have examples of removing or keeping lines by string value, or line numbers. I just cannot figure out how to make my DateTime comparison result as string value so I can rewrite the file. – Skysmith Nov 21 '19 at 23:53

2 Answers2

1

I believe with the format you're using for the date in the log file, you can avoid the DateTime.Parse portion and just use string comparison:

public static void DeleteOldLines(string filePath, DateTime minDate)
{
    // Convert the specified date to the format used in the log file
    var dateStr = minDate.ToString("yyyy-MM-dd");

    // Re-write the file with only lines that have the same or more recent date
    // Note I added a check for the Length to avoid an exception on Substring
    File.WriteAllLines(filePath, File.ReadAllLines(filePath)
        .Where(line => line.Length < 10 || line.Substring(0, 10).CompareTo(dateStr) > -1));
}

This works using the following text file:

2019-11-21 this is today
2019-11-22 this is tomorrow
2019-11-23 this is day after tomorrow
2019-11-20 this is yesterday
2019-11-19 this is day before yesterday
2019-01-01 this is january 1 this year
2020-01-01 this is january 1 next year
2018-01-01 this is january 1 last year

And then:

DeleteLinesOlderThan(@"f:\public\temp\temp.txt", DateTime.Today);

Result:

2019-11-21 this is today
2019-11-22 this is tomorrow
2019-11-23 this is day after tomorrow
2020-01-01 this is january 1 next year
Rufus L
  • 36,127
  • 5
  • 30
  • 43
1

I would read all lines and then create a new list with only the lines you want to keep. Then overwrite the old file with the new.

public static void CleanupTimeLog(string path)
{
    var lines = File.ReadAllLines(path);
    var tempFile = Path.GetTempFileName();
    File.WriteAllLines(tempFile, lines);

    var saveList = new List<string>();
    foreach (var line in lines)
    {
        var date = line.Split(' ')[0];
        if (DateTime.TryParse(date, out DateTime result))
        {
            if (result.AddDays(13) >= DateTime.Now.Date)
            {
                saveList.Add(line);
            }
        }
    }

    File.WriteAllLines(path, saveList);
    File.Delete(tempFile);
}

Usage of temp file is for safety in case something went wrong.

Sach
  • 10,091
  • 8
  • 47
  • 84