流混乱,理解缓冲

时间:2013-10-04 09:43:37

标签: c#

我正在用C#编写自己的XML和CSV解析器(为了好玩),并且在让我的流工作时遇到一些麻烦。基本上我想用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();

如果您能澄清以下内容,我将非常感激:

  • 为什么这种方法会这么慢?
  • 在第二个循环中,是否会自动从先前位置读取+ 1024个字符?
  • 当我到达流的末尾时会发生什么?当剩下&lt; 1024时,它会尝试将1024个字符放入缓冲区?

2 个答案:

答案 0 :(得分:3)

首先,正如@Leff所说,你正在使用

csvChunk += c;

在每个赋值上创建一个新的字符串对象,因为该字符串是一个不可变对象。 您可以改用 StringBuilder 。 另一件可以提高性能的方法是 BufferedStream

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

此外,您不需要使用Peek方法检查,Read(...)方法返回读入数组的总字节数,因此您的while语句将显示:

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

关于第二个问题: 第三:如果剩下 n 个字节,并且n&lt; buffer.Length,它读取n个字节,将它们放入缓冲区数组,然后返回 n

答案 1 :(得分:0)

您应该阅读有关c#字符串的更多信息,这些字符串是不可变的。所以,每次你做这样的事情

csvChunk += c;

为输入文件中的每个字符创建新的字符串对象....

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