C#开放和读取流缓慢?

时间:2014-06-10 20:21:12

标签: c# stream

我有22k文本(rtf)文件,我必须附加到最后一个文件。

代码看起来像这样:

    using (TextWriter mainWriter = new StreamWriter(mainFileName))
    {
        foreach (string currentFile in filesToAppend)
        {
            using (TextReader currentFileRader = new StreamReader(currentFile))
            {
                string fileContent = currentFileRader.ReadToEnd();
                mainWriter.Write(fileContent);
            }
        }
    }

显然,这会打开22k倍的流来从文件中读取。

我的问题是:

1)一般情况下,打开一个缓慢的操作流?从流中读取是否运行缓慢?

2)如果我将文件读作byte []并将其作为byte []附加而不是使用文件文本,那有什么不同吗?

3)合并22k文件的任何更好的想法?

感谢。

3 个答案:

答案 0 :(得分:3)

  

1)一般来说,打开一个缓慢的操作流?

不,一点也不。打开流非常快,只需要从底层操作系统中保留句柄。

  

2)如果我将文件读作byte []并附加它,那有什么区别吗?   as byte []比使用文件文件?

当然,它可能会更快一些,而不是使用某些编码将字节转换为字符串,但与我在下一点建议的情况相比,改进可以忽略不计(特别是如果你处理的是非常大的文件)

  3)任何实现这一目标的方法更好吗? (合并22k文件)

是的,不要将每个文件的内容加载到内存中,只需将其读取为块并将其吐出到输出流:

using (var output = File.OpenWrite(mainFileName))
{
    foreach (string currentFile in filesToAppend)
    {
        using (var input = File.OpenRead(currentFile))
        {
            input.CopyTo(output);
        }
    }
}

BCL中的Stream.CopyTo方法将在我的例子中处理繁重的工作。

答案 1 :(得分:1)

从文件中读取数据的缓慢之处在于,您不能绕电子移动,这些电子可以以非常快的速度传播信号。要读取文件中的信息,您必须实际旋转这些金属磁盘并使用磁铁从中读取数据。这些磁盘的旋转速度远远低于电子通过导线传播信号的速度。无论你在代码中使用什么机制来告诉这些磁盘旋转,你仍然需要等待它们进入一个旋转状态'而这需要时间。

您是将数据视为字节还是文本并不是特别相关的。

答案 2 :(得分:1)

加快这一过程的最佳方法可能是确保输出文件与输入文件位于不同的物理磁盘驱动器上。

此外,通过使用大缓冲区创建输出文件,可以提高速度。例如:

using (var fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None, BufferSize))
{
    using (var mainWriter = new StreamWriter(fs))
    {
        // do your file copies here
    }
}

那就是说,你的主要瓶颈就是打开文件。如果那些22,000个文件都在同一目录中,则尤其为真。 NTFS在大目录中存在一些问题。你最好将一个大目录分成22个目录,每个目录有1,000个文件。从包含数万个文件的目录中打开文件比在只有几百个文件的目录中打开文件要慢得多。