将文件从一个目录复制到另一个目录的最快方法

我需要将文件从一个目录复制到另一个目录,具体取决于SQL数据库表中是否存在文件名。

为此,我使用以下代码:

using(SqlConnection connection = new SqlConnection("datasource or route")) { connection.Open(); using(SqlCommand cmd = new SqlCommand("SELECT idPic, namePicFile FROM DocPicFiles", connection)) using (SqlDataReader reader = cmd.ExecuteReader()) { if (reader != null) { while (reader.Read()) { //picList IS AN ARRAY THAT Contains All the files names in a directory if (picList.Any(s => s.Contains(reader["namePicFile"].ToString()))) { File.Copy("theFile in the Directory or array picList", "the destiny directory"+ ".jpg", false) } } } } } 

有没有什么办法可以在更短的时间内完成? 这需要1小时,为20.876记录。

由于你的i / o子系统几乎肯定是这里的僵局,使用并行任务库可能就像它获得的一样好:

 static void Main(string[] args) { DirectoryInfo source = new DirectoryInfo( args[0] ) ; DirectoryInfo destination = new DirectoryInfo( args[1] ) ; HashSet filesToBeCopied = new HashSet( ReadFileNamesFromDatabase() , StringComparer.OrdinalIgnoreCase ) ; // you'll probably have to play with MaxDegreeOfParallellism so as to avoid swamping the i/o system ParallelOptions options= new ParallelOptions { MaxDegreeOfParallelism = 4 } ; Parallel.ForEach( filesToBeCopied.SelectMany( fn => source.EnumerateFiles( fn ) ) , options , fi => { string destinationPath = Path.Combine( destination.FullName , Path.ChangeExtension( fi.Name , ".jpg") ) ; fi.CopyTo( destinationPath , false ) ; }) ; } public static IEnumerable ReadFileNamesFromDatabase() { using ( SqlConnection connection = new SqlConnection( "connection-string" ) ) using ( SqlCommand cmd = connection.CreateCommand() ) { cmd.CommandType = CommandType.Text ; cmd.CommandText = @" select idPic , namePicFile from DocPicFiles " ; connection.Open() ; using ( SqlDataReader reader = cmd.ExecuteReader() ) { while ( reader.Read() ) { yield return reader.GetString(1) ; } } connection.Close() ; } } 

File.Copy和它一样快。 您必须记住,您依赖于硬件和20000文件指定的文件传输速度,数据访问的延迟也会发挥作用。 如果你在硬盘驱动器上这样做,你可以看到切换到SSD或其他快速介质后的重大改进。

仅就这种情况而言,硬件很可能是您的瓶颈。

编辑:我认为保持与数据库的连接打开这么长时间是一种不好的做法。 我建议你在一些内存缓存(数组,列表,等等)中获取所有需要的数据,然后在复制文件时迭代它。 数据库连接是一种宝贵的资源,在必须处理高并发性(但不仅仅是)的应用程序上,快速释放连接是必须的。

请允许我猜一下 – 嗯…… 不,没有办法更快地做到这一点。

为什么我如此自信? 因为文件复制需要与磁盘通信,这是一个非常慢的操作。 更进一步,如果你试图进行multithreading,结果会变得更慢而不是更快,因为将磁头移动到磁盘上的“机械”操作不再是连续的,这可能是偶然的。

看到我之前问过的这个问题的答案 。

所以是的,如果你还没有使用SSD,请尝试使用SSD,否则你已经获得了最好的function。

下面是我们要了解一下与缓存相比,磁盘写入速度慢的原因如果缓存访问需要10分钟,则意味着从磁盘读取需要2年时间。 所有访问都显示在下图中。 显然,当您的代码执行时,瓶颈就是磁盘写入。 您可以做到最好,让磁盘写入保持顺序。

在此处输入图像描述

我通过创建单个压缩文件(.zip)使用参数来存储文件(无压缩)来解决这个问题。 创建单个(.zip)文件,移动该单个文件,然后在该位置进行扩展,在处理数千个文件时速度提高了2倍。