5

StreamReaderのPeek()メソッドを使用して、処理する必要のある行がまだあるかどうかを確認します。私のファイルには1000行を超えていますが、Peek()はline#750に達すると突然-1を返します。チェックしましたが、ライン#750と#751に違いはないようです。line#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
}

そうすれば、1 か所だけを読むことができます。読めるかどうかをチェックしてから読むよりも、なんとなく正気に感じます。

IEnumerable<string>また、TextReader(または 、またはファイル名から)を作成するメソッドを記述してFunc<TextReader>、これらすべてをより快適にすることもできます。ファイルを読み取るだけで .NET 4 を使用している場合File.ReadLinesは、既に組み込まれています。

編集: のドキュメントから、-1 を取得する理由の 1 つを次に示しますStreamReader.Peek

次に読み取る文字を表す整数。読み取る文字がない場合、またはストリームがシークをサポートしていない場合は -1。

ストリームはシークをサポートしていますか?

于 2012-02-21T11:38:33.043 に答える
6

あなたのケースでPeek Methodが -1 を返す理由はわかりませんが、 StreamReader Classを使用してファイルの最後まで行を読み取る通常の方法は、が返されるまでReadLine Methodを繰り返し呼び出すことです。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 メソッドは、ファイルの終わりまたは別のエラーが発生したかどうかを判断するために整数値を返します。これにより、ユーザーは返された値が -1 であるかどうかを最初に確認してから、Char 型にキャストできます。

おそらく、SQL コマンドで間違ったデータ変換を確認してください。この方法も機能するはずです!

于 2016-06-27T07:26:06.573 に答える
0

認証が必要なアプリケーションとやり取りしようとしたときに、同様の問題に遭遇しました。ファンキーな文字 (Unicode 文字?) に遭遇すると Peek() は -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 に答える