2013-10-04 84 views
1

我正在C#中編寫我自己的XML和CSV解析器(爲了好玩),並且讓我的流工作時遇到了一點麻煩。基本上我想通過char加載文件char並以這種方式讀取它。我通常會做readline,但這對我現在正在做的事情以及我打算在將來做的事情來說太簡單了。它似乎工作,但它要麼非常緩慢,要麼在無限循環中工作。輸出似乎沒問題,但需要一段時間。流混淆,瞭解緩衝區

我一直在MSDN上進行大量的閱讀,試圖理解Streaming,但我無法理解當前的流位置。

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

如果你能澄清以下我將非常感激:

  • 爲什麼會變成這樣的做法是如此之慢?
  • 在第二個循環周圍從前面的位置+ 1024個字符自動讀取?
  • 當我到達流結束附近時會發生什麼,並且當有< 1024剩餘時,它會嘗試將1024個字符導入緩衝區?

回答

3

首先,@Leff說,你正在使用

csvChunk += c; 

其正在對各分配一個新的字符串對象的字符串是不可變對象。 您可以改爲使用StringBuilder。 可能會改善您的表現的另一件事是BufferedStream

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

而且,你不需要檢查與Peek方法,讀(...)方法返回讀入數組中的字節總數,所以你的while語句看起來:

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

關於你的第二個問題: 三:如果有ň字節離開,和n < buffer.Length,它會讀取n個字節,把它們放到緩衝區數組,並返回ñ

+0

真棒答案,謝謝 – Sam

0

您應該閱讀更多關於c#字符串的信息,這些字符串是不可變的。所以,每次你做這樣的事情

csvChunk += c; 

創建新的字符串對象......在你的輸入文件的每一個字符。

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

+0

你會如何建議我處理字符串建設?我已經閱讀了MSDN文檔(非常有趣的BTW,謝謝),但似乎沒有提到任何好的選擇。 – Sam

+0

@Sam有一個名爲'StringBuilder'的類http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx – Sean