Copy multiple files to stream

I have the following script, I have to copy several (about 10,50,200, ...) files. I do it synchronously one by one. This is my piece of code for this.

static void Main(string[] args) { string path = @""; FileSystemWatcher listener = new FileSystemWatcher(path); listener.Created += new FileSystemEventHandler(listener_Created); listener.EnableRaisingEvents = true; while (Console.ReadLine() != "exit") ; } public static void listener_Created(object sender, FileSystemEventArgs e) { while (!IsFileReady(e.FullPath)) ; File.Copy(e.FullPath, @"D:\levani\FolderListenerTest\CopiedFilesFolder\" + e.Name); } 

So, when files are created in a folder and they are ready to use, I copy this file one by one, but I need to start copying as soon as any file is ready for use. Therefore, I think I should use Threads. So. How to implement parallel copying?

@Chris

Check if the file is ready

 public static bool IsFileReady(String sFilename) { // If the file can be opened for exclusive access it means that the file // is no longer locked by another process. try { using (FileStream inputStream = File.Open(sFilename, FileMode.Open, FileAccess.Read, FileShare.None)) { if (inputStream.Length > 0) { return true; } else { return false; } } } catch (Exception) { return false; } } 
+4
source share
3 answers

Performing parallel input / output from a mechanical disk is a bad idea and will only slow down, since the mechanical head must rotate each time to look for the next place to read (a very slow process), and then will bounce as each thread starts its turn.

Follow a consistent approach and read files in a single stream.

+11
source

Now only this (as @Tudor says), but copying files in parallel will create a mess from your hard drive due to fragmentation. In my application, I use copied copying of 200 previously created files simultaneously, just to put them on the hard drive in a linear fashion.

You can read a few more related articles here .

+1
source

Maybe you can have one Thread that does all the processing ie

 Queue files = new Queue(); static void Main(string[] args) { string path = @""; FileSystemWatcher listener = new FileSystemWatcher(path); Thread t = new Thread(new ThreadStart(ProcessFiles)); t.Start(); listener.Created += new FileSystemEventHandler(listener_Created); listener.EnableRaisingEvents = true; while (Console.ReadLine() != "exit") ; } public static void listener_Created(object sender, FileSystemEventArgs e) { files.Enqueue(e.FullPath); } void ProcessFiles() { while(true) { if(files.Count > 0) { String file = files.Dequeue(); while (!IsFileReady(file)) ; File.Copy(file, @"D:\levani\FolderListenerTest\CopiedFilesFolder\" + file); } } } 

And in your listener event, add the file name to the queue.

Then in Thread you can grab the file name from the queue and do your processing there.

+1
source

All Articles