1

私は独自の XML および CSV パーサーを C# で (楽しみのために) 書いていますが、ストリームを動作させるのに少し問題があります。基本的に、ファイル char を char ごとにロードして、そのように読みたいと思います。私は通常 readline を実行しますが、それは私が現在行っていることと将来行う予定のことに対して少し単純すぎます。動作しているように見えますが、非常に遅いか、無限ループで動作しています。出力は問題ないようですが、しばらく時間がかかります。

ストリーミングを理解するために MSDN をよく読んでいますが、現在のストリームの位置を理解するのに苦労しています。

List<string> s = new List<string>();
StreamReader r = File.OpenText(f.FullName);
StreamWriter w = File.CreateText(@"C:\Users\XXXXX\Desktop\streamoutput.txt");
char[] buffer = new char[1024];
int count = 0;
string csvChunk = "";

while (r.Peek() >= 0) //Before end of file?
{
    r.Read(buffer, 0, buffer.length); //Attempting to load in 1024 characters

    foreach (char c in buffer)
    {
        if(c == ','){
            s.Add(csvChunk);
            csvChunk = "";
        }
        else
        {
            csvChunk += c;
            w.Write(c); //Write output to file (so I can see what is going on)
            count++;    //Number of chars done  
        }
    }
   Console.Clear();
   Console.WriteLine("Written " + count + " characters "); //Just to keep track of whats up

}
r.Close();
w.Close();

次の点を明確にしていただければ幸いです。

  • なぜこのアプローチはとても遅いのでしょうか?
  • 2 回目のループでは、前の位置 + 1024 文字から自動的に読み取りますか?
  • ストリームの終わり近くに到達し、残りが 1024 文字未満のときに 1024 文字をバッファに取り込もうとするとどうなりますか?
4

2 に答える 2

3

まず、@Leffが言ったように、あなたは使用しています

csvChunk += c;

文字列は不変オブジェクトであるため、割り当てごとに新しい文字列オブジェクトを作成しています。代わりにStringBuilderを使用できます。パフォーマンスを向上させる可能性のあるもう 1 つのことはBufferedStreamです。

var bufStream = new BufferedStream(<your stream reader>, buffer.Length);

また、Peek メソッドで確認する必要はありません。Read(...) メソッドは、配列に読み込まれた合計バイト数を返すため、while ステートメントは次のようになります。

while(bufStream.Read(buffer, 0, buffer.Length) != 0) 
{...}

2 番目の質問:はい 3 番目: nバイトが残っていて、n < buffer.Length の場合、n バイトを読み取り、それらをバッファー配列に入れ、n を返します

于 2013-10-04T10:09:56.313 に答える
0

不変のC#文字列についてもっと読むべきです。だから、あなたがこのようなことをするたびに

csvChunk += c;

入力ファイルのすべての文字に対して、新しい文字列オブジェクトを作成します。

http://msdn.microsoft.com/en-us/library/362314fe.aspx

于 2013-10-04T09:55:27.377 に答える