Search code examples
c#.netstreamreader

StreamReader.ReadLine will hang in an infinite loop


I have a simple program to read a file using the StreamReader and process it line by line. But the file I am reading may sometimes locate in a network folder. I came across while doing some testing with such a file, that if the network connection lost at some point while I am reading, it'll stay in the same line again and again looping in an infinite loop by resulting the same line as the result from stream.ReadLine().

Is there a way I can find when the fileHandle is not available from the stream itself? I was expecting a FileNotAvailableException kind of an exception would fire when the filehandle is lost from the StreamReader.

Here's my code snippet...

        string file = @"Z://1601120903.csv"; //Network file
        string line;
        StringBuilder stb = new StringBuilder();      
        StreamReader stream = new StreamReader(file, Encoding.UTF8, true, 1048576);
        do
        {
            line = stream.ReadLine();
            // Do some work here
        } while (line != "");

Solution

  • Correct approach 1 (EndOfStream) :

    using(StreamReader sr = new StreamReader(...)) {
        while(!sr.EndOfStream) {
            string line = sr.ReadLine();
            Console.WriteLine(line);
        }
    }
    

    Correct approach 2 (Peek)

    using(StreamReader sr = new StreamReader(...)) {
        while(sr.Peek() >= 0) {
            string line = sr.ReadLine();
        }
    }
    

    Note: that it is incorrect to threat an empty string as end of file.

    if the network connection lost at some point while I am reading, it'll stay in the same line again and again looping in an infinite loop by resulting the same line as the result from stream.ReadLine()

    I've checked this scenario right now - the System.IO.IOException ("The network path was not found."} should be thrown in this case.

    Wrapping this with a try catch block will not fix my problem, will it?

    In this case you can break the reading as follows:

    string line;
    do {
        try {
            line = sr.ReadLine();
            // Do some work here
        }
        catch(System.IO.IOException) {
            break; 
        }
    } while(line != null);