1

In c# I want to access a certain line of a file to rewrite it without changing the rest. Actually doing this way:

using (StreamWriter writer = new StreamWriter(myfile))
{
    for (int currentLine = 1; currentLine <= lines.Length; ++currentLine)
    {
        if (currentLine == Linetoedit)
        {
             writer.WriteLine(stufftowrite);
             return;
        }
        else
        {
            //do nothing
        }
    }
}

The problem is that the file can be big making me afraid that the system can be slowed by this. Any solution to avoid the loop and access, in a more direct way, to the desired line in the file?

Restro Fad
  • 25
  • 7
  • you mean you just want to stop looping after you found the line in your example, or have no loops at all in general? – CuccoChaser Oct 20 '14 at 09:56
  • If you are using C# 4.0, here are a few thoughts. http://stackoverflow.com/questions/1262965/how-do-i-read-a-specified-line-in-a-text-file – Francois Oct 20 '14 at 10:03
  • 1
    I don't see how to use a dictionary to write in a file. I want to write the file in a certain line, i already know the line i want to edit. On the other hand i had already read the post you propose, the problem is that this post is about how to read not write. – Restro Fad Oct 20 '14 at 10:09

2 Answers2

0

From what it sounds like, this won't be possible. You can't randomly jump to a position based on the characters there, so you have to read up until you find the line to replace, hence a loop. The only way you could it without a loop is if the lines are the same length, where you would say "I want line number x," thus you want to seek to x * [line length]. So that's simple, but also a relatively restricted setup.

That said, if you're looking at replacing just one single line, you'll likely have to worry about line length anyway. You can't "insert" into a stream, you can only pick a starting position and write out ensuing bytes. Thus, if you tried to replace a line of length 40 characters with one of length 60, you would wind up writing 18 (60 - 40 - "\r\n".Length) characters into the next line.

So basically there are two scenarios here:

  1. Constant Line Length: Seek through the stream, that negates your loop
  2. Variable Line Length: You have to loop, but that's okay because you'll have to rewrite any data that follows your replaced line anyway.

I suppose I could also tack on a third scenario, where you're guaranteed that your replacement string is exactly the same length as the original one. Then you have to loop only to that line. But that's really just an aggregate of the aforementioned two.

Obviously, there are some nicer ways (arguably) to perform this function. Simpler ways, at least. But I don't get the impression that's what you're asking for here.

If you're truly desperate for performance and if the file is sorted or indexed in some way, for instance, you could write a simple binary search that seeks around the file. Although that would only be even marginally beneficial with a truly big file.

Honestly, though. Unless you are dealing with a "truly big file," I'd be somewhat surprised to see any of this take all that much time. And if you are, it might be worth looking into architecting your application in such a way that you can allow for that. IO is inherently expensive, and thus difficult to optimize as much as we'd sometimes like, so you'll probably want a progress bar or equivalent to show your user that something is happening.

Matthew Haugen
  • 12,916
  • 5
  • 38
  • 54
0

You can't insert line in the middle of a text file without rewriting the rest of the file. Overwriting is only possible if you work with a binary file with records of fixed length. It's a limitation of the disk storage, which stores the files in chunks internally.

See the following discussion for the details: Inserting text into file at specific offset using Win32 API

Community
  • 1
  • 1
George Polevoy
  • 7,450
  • 3
  • 36
  • 61