1

I have a piece of code that is adding lines of text to a System.IO.StringWriter.

When it gets above a certain size, I want to purge lines from the beginning.

How do I do that? Can it be done?

System.IO.StringWriter log = new System.IO.StringWriter();
log.WriteLine("some text");
log.WriteLine("more text");

// some how remove the first line ????
Graham
  • 7,807
  • 20
  • 69
  • 114
  • No - these lines are not written to disk at this point – Graham Dec 09 '19 at 08:58
  • Either keep lines in memory and write only required lines to the file in the end, either write to the file and in the end create another file and copy only required lines from original file. – Ulugbek Umirov Dec 09 '19 at 09:00
  • What do you mean for _size_? Number of lines or total length of text? – Steve Dec 09 '19 at 09:08
  • I mean number of lines – Graham Dec 09 '19 at 09:11
  • Ulugbek Umirov, how do I write only required lines. In other words, how do I access the content of each line? – Graham Dec 09 '19 at 09:12
  • How about a queue that limits the number of entries before you even attempt to write to your destination? [See here](https://stackoverflow.com/questions/5852863/fixed-size-queue-which-automatically-dequeues-old-values-upon-new-enques) – Biesi Dec 09 '19 at 09:12

3 Answers3

6

A possible solution to your problem involves the use of the Queue class. You can add your text to this object and when it reaches a certain size you start trimming away the initial data

For example

void Main()
{
    int maxQueueSize = 50;
    var lines = File.ReadAllLines(filePath);
    Queue<string> q = new Queue<string>(lines);

    // Here you should check for files bigger than your limit    
    ....

    // Trying to add too many elements
    for (int x = 0; x < maxQueueSize * 2; x++) 
    {
        // Remove the first if too many elements
        if(q.Count == maxQueueSize)
            q.Dequeue();

        // as an example, add the x converted to string                
        q.Enqueue(x.ToString());

    }
    // Back to disk
    File.WriteAllLines(filePath, q.ToList());
}
Steve
  • 213,761
  • 22
  • 232
  • 286
4
System.IO.StringWriter log = new System.IO.StringWriter();
log.WriteLine("some text");
log.WriteLine("more text");

// some how remove the first line ????

var sb = log.GetStringBuilder(); //get the underlying StringBuilder
var newLinePosition = sb.ToString().IndexOf(Environment.NewLine); //find the first newline
sb.Remove(0, newLinePosition + Environment.NewLine.Length); //remove from start to the newline... including the newline itself
DarkSquirrel42
  • 10,167
  • 3
  • 20
  • 31
1

You can, instead of writing to a stream write to a different data structure (such as a list) and use an iterator to loop over your lines and replace them if you hit a certain threshold.

List<string> log = new List<string>();
int idx = 0;

//...
if (idx > 10) // your max amount of messages
{
    idx = 0;
}
if (log.Count < idx)
{
    log.Add("more Text");
}
else
{
    log[idx] = "more Text";
}

of course you should wrap this in a class for logging.

FalcoGer
  • 2,278
  • 1
  • 12
  • 34