4

I Im trying to read from one text file and write to another one. The file Im reading from has 2023 lines, and the file that I am writing to comes out with only 2008 lines. I cant figure out what is happening to the other line... Im losing them somewhere. What am I doing wrong?

thanks!

heres my code in C#.

     static void Main(string[] args)
    {
        StreamWriter writer = new StreamWriter("C:/Users/Rafael/desktop/newfile.txt");
        StreamReader reader = new StreamReader("C:/Users/Rafael/desktop/new1.txt");//, System.Text.Encoding.GetEncoding("ISO-8859-1"));
        string line;
        while ((line = reader.ReadLine()) != null)
        {

            writer.WriteLine(line);
        }

    }
iandotkelly
  • 9,024
  • 8
  • 48
  • 67
Rafael Moreira
  • 1,759
  • 2
  • 19
  • 20

5 Answers5

9

At no point here are you closing the streamwriter - so it might not be written to the file. You can test this by putting a Close() call after the loop, or if you have not finished with the file, you can use Flush().

Given a choice, I would however rewrite the code to use Using{} blocks which would close the streams automatically by calling Dispose() when they go out of scope.

iandotkelly
  • 9,024
  • 8
  • 48
  • 67
5

Most likely is that the output isn't being flushed since you aren't calling Dispose() on the writer, so the buffered output is being thrown away.

When you're using classes that implement IDisposable in this way, you should always wrap them in using blocks:

static void Main(string[] args)
{
    using (StreamWriter writer = new StreamWriter("C:/Users/Rafael/desktop/newfile.txt"))
    using (StreamReader reader = new StreamReader("C:/Users/Rafael/desktop/new1.txt"))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {

            writer.WriteLine(line);
        }
    }
}
porges
  • 30,133
  • 4
  • 83
  • 114
  • well, I would say "if possible" wrap them in using blocks; that won't work if you are opening a file to be used and stored through multiple calls, say, in a member variable. – shelleybutterfly Aug 14 '11 at 03:59
  • @shelleybutterfly: Then the thing that owns the `StreamWriter` should itself implement `IDisposable` and call `StreamWriter.Dispose` in the implementation of `Dispose` for that thing. – jason Aug 14 '11 at 04:00
  • @shelleybutterfly: by "using classes" I meant in-line code like this. Of course, what you've said is correct, and the containing class should then be `IDisposable` and so on. – porges Aug 14 '11 at 04:01
  • @Yahia: Actually, he wasn't. The syntax he had is [perfectly legal](http://stackoverflow.com/questions/1329739/nested-using-statements-in-c/1329757#1329757) for `using` blocks. – jason Aug 14 '11 at 04:02
  • @Jason: I'd rather point out that omitting braces is legal around *any* single-statement block. Saying it like that makes `using` seem special, when it isn't. – porges Aug 14 '11 at 04:04
  • @Porges - I totally agree with your approach in this case, however 'always' is a strong word. I use and write classes that implement IDisposable for lots of reasons, and it isn't always possible to put them in a Using{} block. You might have to retain a reference to the object at a class scope, in which case I dispose of it at some specific other point, such as in a Dispose() method of the encapsulating class. – iandotkelly Aug 14 '11 at 04:26
  • @iandotkelly, shelleybutterfly: I amended the sentence to say "when youre using [them] in this way" to clear that up :P – porges Aug 14 '11 at 04:54
3

This is where implementation details matter a lot. Basically when you write to a StreamWriter, the text that you write isn't necessarily committed to the file on the disk. Instead, it could sit in a buffer somewhere and that buffer has to be flushed to be committed to the disk. Periodically, this buffer will be flushed by the StreamWriter itself. But if you let your process terminate without making a final flush, the buffer could still hold uncommitted writes.

So, call writer.Flush, writer.Close, writer.Dispose, or best of all, wrap your use of the StreamWriter in a using block so that it's disposed for you.

jason
  • 236,483
  • 35
  • 423
  • 525
2

Also, if you are not wanting to close the file. You could use flush.

Justin
  • 6,373
  • 9
  • 46
  • 72
1

ReadLine() returns an empty string when the line doesn't contain any characters... Call Flush() and Close() ... consider using using...

Why aren't you just copying the file as a whole (File.Copy) ?

Yahia
  • 69,653
  • 9
  • 115
  • 144
  • I didnt use File.Copy because i had to do some sorting on the strings before I could write it back to the new file. But calling flush() solved my problem. thanks for the help. – Rafael Moreira Aug 15 '11 at 14:24