Reputation: 559
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 != "");
Upvotes: 13
Views: 10567
Reputation: 1894
If your stream is a NetworkStream, the ReadLine method will expect more content from the stream, if it reached at end, indefinitely. I think, and according to the StreamReader documentation, it is designed to work only with local file streams. In this case, you can read bytes directly from the NetworkStream.
Upvotes: 0
Reputation: 2246
One more way would be to use File.ReadAllLines() and it will take care of opening file and reading all lines and closig the file and may also handle scenario when network connection is lost.
var lines = File.ReadAllLines("Z://1601120903.csv");
foreach(line in lines)
{
// Do some work
}
Upvotes: 1
Reputation: 17850
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);
Upvotes: 9
Reputation: 186668
Compare with null
not with empty string:
https://msdn.microsoft.com/en-us/library/system.io.streamreader.readline(v=vs.110).aspx
Return Value Type: System.String The next line from the input stream, or null if the end of the input stream is reached.
do
{
line = stream.ReadLine();
// Do some work here
} while (line != null);
A better approach, however, is to let .Net do the work (line by line file reading) for you and drop all readers:
foreach (String line in File.ReadLines(file)) {
// Do some work here
}
Upvotes: 19
Reputation: 1254
Assuming the file shouldn't change while you reading it and it's not huge, you might want to consider to copy it to a temp file (locally) and then work on it without interference.
If you want to get index of the place you reached this might help: How to know position(linenumber) of a streamreader in a textfile?
Upvotes: 0
Reputation: 7656
If you write it with a while
-loop:
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
Upvotes: 4