Click here to Skip to main content
15,893,161 members
Please Sign up or sign in to vote.
2.50/5 (4 votes)
See more:
I have try this code but it take 2-3 hours to execute can we make it fast ??

VB
For Each _FileName As String In arrFileLines
     For Each _file As String In Directory.GetFiles(sSourcePath, "*.*", SearchOption.AllDirectories)
        If _FileName = Path.GetFileName(_file) Then
                  File.Copy(_file, Path.Combine(sDestPath, _FileName))
        End If
     Next
 Next


Where arrFileLine store the name of search files and sSourcePath is serching directory and sDestPath is destination direcotry.
Posted
Comments
[no name] 3-Aug-15 7:34am    
Disk access is slow, fact of life. Searching disk drives is slow, fact of life. Did you try searching for just the files you want instead of searching every single file? Get a list of files once and then search the list.
Dharmesh .S. Patil 3-Aug-15 7:35am    
Ok Thanks for suggestion.
F-ES Sitecore 3-Aug-15 9:04am    
Change the "*.*" pattern to the filename which you already know. Or you could load all the files returned from your *.* search into an array just the once, then look in that array for each file in arrFileLines. That way the slow part (the search) is only done once and not once for each file.
Dharmesh .S. Patil 3-Aug-15 9:16am    
Thank you.

Adding to what Aday Wes said in the comments above("Disk access is slow, fact of life. Searching disk drives is slow, fact of life. Did you try searching for just the files you want instead of searching every single file? Get a list of files once and then search the list."), You can also use Windows search index to make your search even faster:

1) Ask Windows indexer to index your search folder
http://www.wikihow.com/Add-a-Folder-to-the-Windows-7-File-Index[^]
2) Programmatically query the windows index first (there are different ways to do it, check the link)https://msdn.microsoft.com/en-us/library/windows/desktop/bb266517(v=vs.85).aspx[^] and then perform your traditional search if the index is unable to find all your files. In most of the cases, it will find out your files if the index is up-to-date.
 
Share this answer
 
Comments
Dharmesh .S. Patil 3-Aug-15 9:19am    
Can you explain me how query apply for it ??
Abhipal Singh 3-Aug-15 12:32pm    
The link in my answer provides the ways by which you can query the index.
Following link is specific to index querying using SQL syntax:
https://msdn.microsoft.com/en-us/library/windows/desktop/bb231256(v=vs.85).aspx
What you have is O(N*M) where N is the number of names in arrFileLines and M is the total number of files returned by the Directory.GetFiles. This can be changed pretty easily to be O(N+M) ... lots faster.
First, load the arrFileLines entries into a HashSet(Of String):
(My VB is worse than rusty...but here goes.)
VB
Dim matchNames As New HashSet(Of String)(arrFileLines)

This is O(N), it depends only on the length of arrFileLines, and is done only once. (In fact, it could be initialized in whatever loop gets the values into arrFileLines instead of building that array (unless the array has additional uses).)

Then scan through all of the files with Directory.EnumerateFiles once and check for matches. (Use Directory.EnumerateFiles instead of Directory.GetFiles because it doesn't require returning all of the files in a huge array.)
VB
For Each _file As String In Directory.EnumerateFiles(sSourcePath, "*.*", SearchOption.AllDirectories)
  Dim fileName as String = Path.GetFileName(_file)
  If matchNames.Contains(fileName) Then
    File.Copy(_file, Path.Combine(sDestPath, fileName))
  End If
Next

The HashSet allows for checking all of the names in arrFileLines at once in constant time.
This part is O(M), as it depends only on the total number of files returned by the Directory.EnumerateFiles().
 
Share this answer
 
v3
Comments
Dharmesh .S. Patil 4-Aug-15 0:07am    
Thank you for detail description it's helpful :) My code is working correctly and fast Thank You so much.
Advice: Running your program with a profiler would help you to see where you spend running time.

The profiler would also help you to see if changes are efficient.
 
Share this answer
 
Comments
Philippe Mori 3-Aug-15 21:26pm    
Good advice but in this case one only need some common sense...
Patrice T 3-Aug-15 22:37pm    
I agree, common sense is enough in this case, but the profiler is a tool that is useful almost everywhere.
When it comes to optimization, there is many tracks to follow to see which one is the best. This were the profiler comes to help you.

Your program is brute force, and some optimizations can be done.

When you got a match and copy the file, you don't need to check the SsourcePath until the end:
VB
For Each _FileName As String In arrFileLines
     For Each _file As String In Directory.GetFiles(sSourcePath, "*.*", SearchOption.AllDirectories)
        If _FileName = Path.GetFileName(_file) Then
             File.Copy(_file, Path.Combine(sDestPath, _FileName))
             Exit for
        End If
     Next
 Next


you also can take advantage of the system
VB
For Each _FileName As String In arrFileLines
     For Each _file As String In Directory.GetFiles(sSourcePath, _FileName, SearchOption.AllDirectories)
        If _FileName = Path.GetFileName(_file) Then
             File.Copy(_file, Path.Combine(sDestPath, _FileName))
        End If
     Next
 Next


Theses 2 tracks are not fully optimized and can be combined. You have to try different solutions ans see how good they are.
 
Share this answer
 
Comments
Dharmesh .S. Patil 4-Aug-15 0:07am    
Thank you for correction :)
Matt T Heffron 4-Aug-15 13:10pm    
This is still O(N*M), see my Solution 2 for an O(N+M) optimization.
Patrice T 4-Aug-15 13:30pm    
I didn't say that my 2 pieces of code are better than yours.
I say that they are better than the example code.
If you look carefuly, you will see that I move part of the job to the system.
Matt T Heffron 4-Aug-15 17:09pm    
Agreed!My note was as much for the OP (or future readers) not to think your solutions were optimal.
Your first optimization introduces a subtle change in behavior in the case where the _FileName would be matched in multiple sub-directories (remember the SearchOption.AllDirectories): yours will copy only the first matching file, while the original and mine will copy all and end up with the last matching file. It may never happen, but...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900