0

I'm reading a file using C# and class TextReader

TextReader reader = new StreamReader(stream);
string line;
while ((line = reader.ReadLine()) != null)
 {
   if (someCondition)
    {
      // I want to change "line" and save it into the file I'm reading from
    }
 }

In a code there is a question: how do I save a changed line to a file I'm reading from and continue reading?

Alan Coromano
  • 24,958
  • 53
  • 135
  • 205
  • You can't reliably read/write in a text file. Only when the new line is exactly the same size (in bytes) you could make it work. Is this the case? – H H Oct 13 '12 at 13:24
  • Hmm, no, this is not. By new line, do you mean a current line which I want to change? – Alan Coromano Oct 13 '12 at 13:26
  • Might be an answer here: http://stackoverflow.com/questions/3817477/simultaneous-read-write-a-file-in-c-sharp – Mike Parkhill Oct 13 '12 at 13:30

4 Answers4

3

Fast and dirty solution would be:

TextReader reader = new StreamReader(stream);
string line;
StringBuilder sb = new StringBuilder();
while ((line = reader.ReadLine()) != null)
{
    if (someCondition)
    {
       //Change variable line as you wish.
    }
    sb.Append(line);
 }

using (StreamWriter sw = new StreamWriter("filePath"))
{
    sw.Write(sb.ToString());
}

or

TextReader reader = new StreamReader(stream);
string line;
String newLines[];
int index = 0;
while ((line = reader.ReadLine()) != null)
{
   if (someCondition)
   {
      //Change variable line as you wish.
   }
   newLines[index] = line;
   index++;
}

using (StreamWriter sw = new StreamWriter("filePath"))
{
    foreach (string l in newLines)
    {
        sw.WriteLine(l);
    }
}

If memory is too important you can try this too:

TextReader reader = new StreamReader(stream);
string line;
while ((line = reader.ReadLine()) != null)
{
   if (someCondition)
   {
      //Change variable line as you wish.
   }
   using (StreamWriter sw = new StreamWriter("filePath"))
   {
       sw.WriteLine(line);
   }
 }
Leri
  • 12,367
  • 7
  • 43
  • 60
  • If the file is large, he will probably want to write directly to the new file and not a StringBuilder (think memory consumption). – driis Oct 13 '12 at 13:32
  • @driis Yes, you are right. It was first thing that came in my mind. I'll update answer, thanks. – Leri Oct 13 '12 at 13:35
2

The easiest thing is to write a new file, then when finished, replace the old file with the new file. This way you only do writes in one file.

If you try to read/write in the same file, you will run into problems when the content you want to insert is not the exact same size as the content it is replacing.

There is nothing magic about text files. They are just a stream of bytes representing characters in a text encoding. There are no line concept in the file, just separators in the form of newline characters.

driis
  • 161,458
  • 45
  • 265
  • 341
2

A very simple solution

void Main()
{
    var lines = File.ReadAllLines("D:\\temp\\file.txt");
    for(int x = 0; x < lines.Length; x++)
    {
        // Of course this is an example of the condtion
        // you should implement your checks
        if(lines[x].Contains("CONDITION"))
        {
            lines[x] = lines[x].Replace("CONDITION", "CONDITION2");
        }

    }
    File.WriteAllLines("D:\\temp\\file.txt", lines);
} 

The drawback is the memory usage caused by the in memory lines, but, if we stay around 50MB, it should be handled effortlessly by modern PC.

Steve
  • 213,761
  • 22
  • 232
  • 286
2

If the file is not too large, you should simply rewrite the whole file:

var lines = File.ReadAllLines(path)
                .Where(l => someCondition);
File.WriteAllLines(path, lines);
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939