流混淆,了解缓冲区

本文关键字:了解 缓冲区 | 更新日期: 2023-09-27 18:34:04

我正在用 C# 编写自己的 XML 和 CSV 解析器(为了好玩(,并且在让我的流工作时遇到了一点麻烦。基本上我想逐个加载文件字符并以这种方式读取它。我通常会做阅读线,但对于我现在正在做的事情和我将来计划做的事情来说,这有点太简单了。它似乎确实有效,但它要么非常慢,要么在无限循环中工作。输出似乎还可以,但需要一段时间。

我一直在 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 个字符?
  • 当我到达流的末尾时会发生什么,当还剩下 1024 个字符时,它会尝试将 1024 个字符放入缓冲区<?

流混淆,了解缓冲区

首先,正如@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<缓冲区。长度,它读取>n

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

csvChunk += c;

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

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