C#:使用 StreamReader 从 txt 文件中读取行,但 Peek() 返回 -1,即使还有很多行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9376887/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C#: Using StreamReader to read line from txt file, but Peek() return -1 even there are a lot of lines left
提问by Alan
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.
我使用 StreamReader 的 Peek() 方法来检查是否还有更多行需要处理。我的文件中有 1000 多行,但是 Peek() 在到达第 750 行时突然返回 -1。我检查过,但 line#750 和 #751 之间似乎没有区别。即使我删除了第 750 行和 751 行,它仍然会在其他行中断。
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.
我试过了while ((x = reader.ReadLine()) != null),但抛出了“无法访问已处理的对象”的异常。
Finally I figured it out by using:
while (stream.CanRead && (x = reader.ReadLine()) != null)
最后我想通了它使用:
while (stream.CanRead && (x = reader.ReadLine()) != null)
回答by dtb
I'm not sure why Peek Methodreturns -1 in your case, but the usual way to read lines with the StreamReader Classto the end of the file is to repeatedly call the ReadLine Methoduntil nullis returned:
我不确定为什么Peek 方法在您的情况下返回 -1,但是使用StreamReader 类将行读取到文件末尾的常用方法是重复调用ReadLine 方法,直到null返回:
string line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
回答by Jon Skeet
While it doesn't explainwhat's going on, I'd personally avoid using Peek. I'd use:
虽然它没有解释发生了什么,但我个人会避免使用Peek. 我会用:
string line;
while ((line = reader.ReadLine()) != null)
{
// Use the line
}
That way you're only readingin one place. It somehow feels more sane than checking whether or not you canread, 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.ReadLinesis already built-in.
您还可以编写一种方法来创建一个IEnumerable<string>from a TextReader(或 from aFunc<TextReader>或文件名),这可以使所有这些变得更加愉快。如果您只是在读取文件并且使用 .NET 4,那么 .NET 4File.ReadLines已经是内置的。
EDIT: Here's one reason you may be getting -1, from the docs of StreamReader.Peek:
编辑:这是您可能从以下文档中获得 -1 的原因之一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.
表示要读取的下一个字符的整数,如果没有要读取的字符或流不支持查找,则为 -1。
Doesyour stream support seeking?
您的流是否支持搜索?
回答by David Jazbec
Do you need to use peek? Are you skipping certain lines? If you want to read all lines use this.
你需要使用窥视吗?您是否跳过某些行?如果您想阅读所有行,请使用它。
while(!sr.EndOfStream)
{
//Do stuff
}
回答by MAXE
As stated in MSDN, Peek Methodnot only returns -1 when you reach the end of the stream, but also in case of internal errors:
正如 MSDN 中所述,Peek Method不仅在到达流末尾时返回 -1,而且在出现内部错误时也返回:
The Peek method returns an integer value in order to determine whether the end of the file, or another error has occurred. This allows a user to first check if the returned value is -1 before casting it to a Char type.
Peek 方法返回一个整数值以确定是文件结束,还是发生了另一个错误。这允许用户在将其转换为 Char 类型之前首先检查返回值是否为 -1。
Maybe check for wrong data conversions in your SQL command, I think this method should work too!
也许检查您的 SQL 命令中的错误数据转换,我认为这种方法也应该有效!
回答by CaMiX
I ran into a similar problem when trying to interact with an application that required authentication. Peek() would return -1 when encountering funky characters (unicode characters?) and ReadLine() was also unreliable and would eventually lockup my application since it seems the process' Standard stream was not closed.
我在尝试与需要身份验证的应用程序交互时遇到了类似的问题。Peek() 在遇到奇怪的字符(unicode 字符?)时会返回 -1,而 ReadLine() 也不可靠,最终会锁定我的应用程序,因为进程的标准流似乎没有关闭。
Using the Read() method was the only way I could assure I got ALL lines and characters. Additionally, using the Process' ErrorDataReceived or OutputDataReceived event handlers also proved UNRELIABLE (missing lines). Below is how I solved my problem and insured all lines, and characters, were received:
使用 Read() 方法是我可以确保获得所有行和字符的唯一方法。此外,使用 Process 的 ErrorDataReceived 或 OutputDataReceived 事件处理程序也证明不可靠(缺少行)。以下是我如何解决我的问题并为所有行和字符投保:
process.Start();
var stdOutput = process.StandardOutput;
StringBuilder fullMessage = new StringBuilder();
while (true)
{
var character = (char)stdOutput.Read();
fullMessage.Append(character);
//Print Out All Characters
Console.Write(character);
if (fullMessage.ToString().EndsWith("Enter Password: "))
{
//Submit Password To Application
using(StreamWriter writer = process.StandardInput){
writer.Write("somepassword");
writer.Flush();
}
break;
}
}

