File.Copy与手动FileStream.Write用于复制文件

我的问题是关于文件复制性能。我们有一个媒体管理系统,它需要将文件系统上的许多文件移动到不同的位置,包括同一网络上的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相关的线程有关缓慢的复制性能)。

改善您的方法性能的一些线索:

  1. 就像前面所说的,从您的循环中删除Flush方法。您根本不需要它。
  2. 增加缓冲区可能有所帮助,但仅对于文件共享操作,对于网络共享或ftp服务器,这会减慢速度。60 * 1024是网络共享的理想选择,至少在vista之前。对于ftp 32k,在大多数情况下就足够了。
  3. 通过提供您的缓存策略(在您的情况下为顺序读取和写入)来帮助OS,使用FileStream构造函数重写和FileOptions参数(SequentalScan)。
  4. 您可以使用异步模式来加快复制速度(对于网络到文件的情况尤其有用),但不要为此使用线程,而应使用重叠的io(.net中的BeginRead,EndRead,BeginWrite,EndWrite),并且不要忘记在FileStream构造函数中设置Asynchronous选项(请参见FileOptions)

异步复制模式示例:

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);

以上是 File.Copy与手动FileStream.Write用于复制文件 的全部内容, 来源链接: utcz.com/qa/415660.html

回到顶部