【问题标题】:Stream confusion, understanding buffers流混淆,理解缓冲区
【发布时间】:2013-10-04 09:43:36
【问题描述】:

我正在用 C# 编写自己的 XML 和 CSV 解析器(为了好玩),并且在让我的流工作时遇到了一些麻烦。基本上我想按字符加载文件并以这种方式读取它。我通常会做 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 个字符?
  • 当我到达流的末尾附近并尝试在剩余

【问题讨论】:

    标签: c#


    【解决方案1】:

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

    csvChunk += c;
    

    在每个赋值上创建一个新的字符串对象,因为字符串是一个不可变的对象。 您可以改用 StringBuilderBufferedStream 可能会提高您的性能。

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

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

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

    关于你的第二个问题:是的 第三:如果还有n个字节,nn

    【讨论】:

      【解决方案2】:

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

      csvChunk += c;
      

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

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

      【讨论】:

      猜你喜欢
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多