2012-06-14 21 views
4

У меня следующий сценарий, я должен скопировать несколько (около 10,50,200, ...) файлов. Я делаю это синхронно один за другим. Это мой фрагмент кода для этого.Копирование нескольких файлов в потоке

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); 
     } 

Так что, когда файлы создаются в какую-нибудь папку и она готова использовать скопировать этот файл один за другим, но мне нужно, чтобы начать копирование, как только любой файл готов к использованию. Поэтому я думаю, что я должен использовать Threads. Итак .. Как реализовать параллельное копирование?

@ Крис

Проверить, если файл готов

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; 
      } 
     } 
+0

Также слово предупреждения ... Я считаю, что созданное событие срабатывает, когда файл сначала создается. Если файл занимает некоторое время для создания, вы можете обнаружить, что вы пытаетесь обработать его до того, как он закончил писать ... – Chris

+1

@ Крис посмотреть здесь, пока (! IsFileReady (e.FullPath)); – levi

+0

D'oh! :) Как вы проверяете это из интереса? Я никогда не нашел особо хороших способов проверить это ... – Chris

ответ

11

Ведение параллельного ввода/вывода из механического диска является плохой идеей, и будет только медленные вещи вниз, как механические потребности голов чтобы вращаться каждый раз, чтобы искать следующее место для чтения (очень медленный процесс), и затем будет отскакивать, когда каждый поток начинает свою очередь.

Придерживайтесь последовательного подхода и читайте файлы в одном потоке.

1

Теперь только это (что говорит @Tudor), но копирование файлов параллельно создаст беспорядок из вашего жесткого диска из-за фрагментации. В моем приложении я использую копирование по очереди из 200 одновременно созданных ранее файлов, просто для того, чтобы поместить их на жесткий диск «линейным» способом.

Вы можете прочитать дополнительную информацию по теме here.

1

Вы могли бы иметь один Thread, который делает всю обработку, т.е.

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); 
     } 
    } 
} 

А в вашем случае listener добавить имя файла в очереди.

Затем в вашем Thread вы можете получить имя файла из очереди и выполнить свою обработку оттуда.

+0

, и все-таки это будет однопоточная синхронная работа, не так ли? – levi

+0

Да, так как вся обработка будет на одном «потоке». Тем не менее, вы все еще можете обработать после того, как «Thread» начал оставлять вас, чтобы перейти к другой обработке в «Main». –

+0

Спасибо, что выглядит красивым – levi

Смежные вопросы