I use Peek() method of StreamReader to check whether there are more lines need to be processed. There are more than 1000 lines in my file, but Peek() suddenly return -1 when it reachs line#750. I checked but seems no differences between line#750 and #751. Even I deleted line#750 and 751, it will still break up at other line.
Below are my codes for your information:
try
{
String ftpserver = ftp + filename;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpserver));
reqFTP.UsePassive = false;
reqFTP.UseBinary = true;
reqFTP.Proxy = null;
reqFTP.Credentials = new NetworkCredential(username, password);
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
response = (FtpWebResponse)reqFTP.GetResponse();
stream = response.GetResponseStream();
reader = new StreamReader(stream, ConfigHelper.MyEncoding);
while (reader.Peek() > -1)
{
string x = reader.ReadLine();
if (x != null)
{
//.......
}
}
}
catch (Exception ex)
{
}
finally
{
if (reader != null)
reader.Close();
if (response != null)
response.Close();
}
I tried while ((x = reader.ReadLine()) != null)
, but an exception of "Cannot access a disposed object" was thrown out.
Finally I figured it out by using:
while (stream.CanRead && (x = reader.ReadLine()) != null)
While it doesn't explain what's going on, I'd personally avoid using Peek
. I'd use:
string line;
while ((line = reader.ReadLine()) != null)
{
// Use the line
}
That way you're only reading in one place. It somehow feels more sane than checking whether or not you can read, and then reading.
You can also write a method to create an IEnumerable<string>
from a TextReader
(or from a Func<TextReader>
, or a filename) which can make all of this more pleasant. If you're just reading a file and you're using .NET 4, then File.ReadLines
is already built-in.
EDIT: Here's one reason you may be getting -1, from the docs of StreamReader.Peek
:
An integer representing the next character to be read, or -1 if there are no characters to be read or if the stream does not support seeking.
Does your stream support seeking?