I need to copy files from one directory to another, depending on the existence of the file name in a table of SQL database.
For this I use the following code:
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)
}
}
}
}
}
Is there any way that this can be done in less time? It takes 1 hour for do that, for 20.876 records.
Since your i/o subsystem is almost certainly the botteneck here, using the parallel task library is probably about as good as it gets:
static void Main(string[] args)
{
DirectoryInfo source = new DirectoryInfo( args[0] ) ;
DirectoryInfo destination = new DirectoryInfo( args[1] ) ;
HashSet<string> filesToBeCopied = new HashSet<string>( 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<string> 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() ;
}
}