C#打开和阅读溪流的速度慢吗?

C#打开和阅读溪流的速度慢吗?,c#,stream,C#,Stream,我有22k的文本(rtf)文件,我必须附加到最后一个 代码如下所示: using (TextWriter mainWriter = new StreamWriter(mainFileName)) { foreach (string currentFile in filesToAppend) { using (TextReader currentFileRader = new StreamReader(currentFile)

我有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文件的方法


谢谢。

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


不管你是将数据视为字节还是文本,这都不是特别相关的。否。

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

不管你是把数据当作字节还是文本,这都不是特别相关的

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

不,一点也不。打开流的速度非常快,只需从底层操作系统保留一个句柄即可

2) 如果我将文件读取为byte[]并附加它,有什么区别吗 作为字节[]而不是使用文件文本

当然,与使用某种编码将字节转换为字符串相比,这可能要快一点,但与我在下一点中建议的相比,这种改进可以忽略不计(特别是在处理非常大的文件时)

3) 有什么方法可以更好地做到这一点?(合并22k文件)

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

using (var output = File.OpenWrite(mainFileName))
{
    foreach (string currentFile in filesToAppend)
    {
        using (var input = File.OpenRead(currentFile))
        {
            input.CopyTo(output);
        }
    }
}
在我的示例中,来自BCL的方法将处理重载

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

不,一点也不。打开流的速度非常快,只需从底层操作系统保留一个句柄即可

2) 如果我将文件读取为byte[]并附加它,有什么区别吗 作为字节[]而不是使用文件文本

当然,与使用某种编码将字节转换为字符串相比,这可能要快一点,但与我在下一点中建议的相比,这种改进可以忽略不计(特别是在处理非常大的文件时)

3) 有什么方法可以更好地做到这一点?(合并22k文件)

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

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

在我的示例中,BCL的方法将处理繁重的工作。

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

另外,通过创建带有大缓冲区的输出文件,可以提高速度。例如:

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

也就是说,您的主要瓶颈将是打开文件。如果那22000个文件都在同一个目录中,情况尤其如此。NTFS对于大目录有一些问题。您最好将一个大目录拆分为22个目录,每个目录包含1000个文件。从包含数万个文件的目录中打开文件要比在只有几百个文件的目录中打开文件慢得多。

最好的加速方法可能是确保输出文件位于与输入文件不同的物理磁盘驱动器上

另外,通过创建带有大缓冲区的输出文件,可以提高速度。例如:

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

也就是说,您的主要瓶颈将是打开文件。如果那22000个文件都在同一个目录中,情况尤其如此。NTFS对于大目录有一些问题。您最好将一个大目录拆分为22个目录,每个目录包含1000个文件。从包含数万个文件的目录中打开文件要比在只有几百个文件的目录中打开文件慢得多。

文件平均有多大?进程的内存使用情况如何?最终文件大约为200-300MB。这不是问题,因为我没有将此文件保存到内存中。我正在将小文件直接写入流中。小文件相对较小-最大100KB请检查进程的内存使用情况。我认为它可能会占用大量内存,因为要将小文件的内容读入内存?如果这是你的观点,@Darim Dimitrov的解决方案将解决这个问题。任何人都记得老式的DOS命令
COPY file1.txt/A+file2.txt/A。。。。。finalfile.txt
?文件平均有多大?进程的内存使用情况如何?最终文件大约为200-300MB。这不是问题,因为我没有将此文件保留在内存中。我正在将小文件直接写入流中。小文件相对较小-最大100KB请检查进程的内存使用情况。我认为它可能会占用大量内存,因为要将小文件的内容读入内存?如果这是你的观点,