5

我使用 StreamReader 的 Peek() 方法来检查是否有更多的行需要处理。我的文件中有 1000 多行,但 Peek() 在到达第 750 行时突然返回 -1。我检查过,但线#750 和#751 之间似乎没有区别。即使我删除了第 750 行和第 751 行,它仍然会在其他行中断。

以下是我的代码供您参考:

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();
}

我试过while ((x = reader.ReadLine()) != null)了,但是抛出了“无法访问已处置的对象”的异常。

最后我通过使用: while (stream.CanRead && (x = reader.ReadLine()) != null)

4

5 回答 5

9

虽然它没有解释发生了什么,但我个人会避免使用Peek. 我会使用:

string line;
while ((line = reader.ReadLine()) != null)
{
    // Use the line
}

这样你就只能在一个地方阅读。不知何故,这比检查你是否可以阅读,然后阅读更理智。

您还可以编写一个方法来创建一个IEnumerable<string>from a TextReader(或 from aFunc<TextReader>或一个文件名),这可以使这一切变得更加愉快。如果您只是在读取文件并且使用的是 .NET 4,那么File.ReadLines它已经是内置的。

编辑:这是您可能从以下文档中获得-1的一个原因StreamReader.Peek

表示要读取的下一个字符的整数,如果没有要读取的字符或流不支持查找,则为 -1。

您的流支持搜索吗

于 2012-02-21T11:38:33.043 回答
6

我不确定为什么Peek Method在您的情况下返回 -1,但是使用StreamReader 类读取文件末尾的行的常用方法是重复调用ReadLine 方法,直到null返回:

string line;
while ((line = reader.ReadLine()) != null)
{
    Console.WriteLine(line);
}
于 2012-02-21T11:38:15.957 回答
4

你需要使用窥视吗?您是否跳过某些行?如果您想阅读所有行,请使用此。

       while(!sr.EndOfStream)
            {
                //Do stuff
            }
于 2012-02-21T14:11:39.483 回答
1

如 MSDN 中所述,Peek 方法不仅在到达流末尾时返回 -1,而且在出现内部错误时也会返回:

Peek 方法返回一个整数值,以确定文件是否结束,或者发生了另一个错误。这允许用户在将其转换为 Char 类型之前首先检查返回的值是否为 -1。

也许检查您的 SQL 命令中的错误数据转换,我认为这种方法也应该有效!

于 2016-06-27T07:26:06.573 回答
0

在尝试与需要身份验证的应用程序交互时,我遇到了类似的问题。Peek() 在遇到时髦字符(unicode 字符?)时会返回 -1,而 ReadLine() 也不可靠,最终会锁定我的应用程序,因为看起来进程的标准流没有关闭。

使用 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;
    }
}
于 2016-09-02T19:39:55.907 回答