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相关的线程有关缓慢的复制性能)。
改善您的方法性能的一些线索:
- 就像前面所说的,从您的循环中删除Flush方法。您根本不需要它。
- 增加缓冲区可能有所帮助,但仅对于文件共享操作,对于网络共享或ftp服务器,这会减慢速度。60 * 1024是网络共享的理想选择,至少在vista之前。对于ftp 32k,在大多数情况下就足够了。
- 通过提供您的缓存策略(在您的情况下为顺序读取和写入)来帮助OS,使用FileStream构造函数重写和FileOptions参数(SequentalScan)。
- 您可以使用异步模式来加快复制速度(对于网络到文件的情况尤其有用),但不要为此使用线程,而应使用重叠的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