我的问题是关于文件复制性能。我们有一个媒体管理系统,它需要将文件系统上的许多文件移动到不同的位置,包括同一网络上的Windows共享,FTP站点,AmazonS3等。当我们都在一个Windows网络上时,就可以摆脱使用System.IO.File.Copy(源,目标)以复制文件。由于很多时候我们只有输入流(如MemoryStream),因此我们尝试抽象化Copy操作以获取输入流和输出流,但是性能却出现了大幅下降。下面是一些用于复制文件以用作讨论点的代码。
public void Copy(System.IO.Stream inStream, string outputFilePath) { int bufferSize = 1024 * 64; using (FileStream fileStream = new FileStream(outputFilePath, FileMode.OpenOrCreate, FileAccess.Write)) { int bytesRead = -1; byte[] bytes = new byte[bufferSize]; while ((bytesRead = inStream.Read(bytes, 0, bufferSize)) > 0) { fileStream.Write(bytes, 0, bytesRead); fileStream.Flush(); } } }
有谁知道为什么它执行比File.Copy慢得多?有什么我可以做以提高性能的吗?我是否只需要放入特殊的逻辑来查看是否要从一个Windows位置复制到另一个窗口- 在这种情况下,我将只使用File.Copy,而在其他情况下,我将使用流?
请让我知道您的想法以及是否需要其他信息。我尝试了不同的缓冲区大小,似乎64k缓冲区大小最适合我们的“小”文件,而256k +缓冲区大小更适合我们的“大”文件-但在任何情况下,它的性能都比File.Copy( )。提前致谢!
File.Copy是基于CopyFile Win32函数构建的,此功能引起了MS工作人员的广泛关注(请记住与Vista相关的线程有关缓慢的复制性能)。
改善您的方法性能的一些线索:
异步复制模式示例:
int Readed = 0; IAsyncResult ReadResult; IAsyncResult WriteResult; ReadResult = sourceStream.BeginRead(ActiveBuffer, 0, ActiveBuffer.Length, null, null); do { Readed = sourceStream.EndRead(ReadResult); WriteResult = destStream.BeginWrite(ActiveBuffer, 0, Readed, null, null); WriteBuffer = ActiveBuffer; if (Readed > 0) { ReadResult = sourceStream.BeginRead(BackBuffer, 0, BackBuffer.Length, null, null); BackBuffer = Interlocked.Exchange(ref ActiveBuffer, BackBuffer); } destStream.EndWrite(WriteResult); } while (Readed > 0);