2016-03-24 7 views
3

[Использование C# и Windows, в качестве платформы]Получение уведомления, когда блокировка файла выпущен

У меня есть камера, которая записывает JPG файлы в локальную папку на моем компьютере. Я хочу загрузить каждый файл, который падает на камеру, поэтому у меня есть FileSystemWatcher, который уведомляет меня всякий раз, когда создается новое изображение, , но камера блокирует файл, когда он записывается, поэтому, если я попытаюсь загрузить его сразу после уведомления его создание, я получаю исключение, говоря, что файл заблокирован.

В настоящее время у меня есть цикл while (с Thread.Sleep), который повторяет загрузку изображения каждые 0,2 секунды, но он чувствует себя немного грязным.

Есть ли более элегантный способ подождать, пока блокировка будет выпущена, поэтому я могу загрузить файл, будучи уверенным, что он больше не используется ??

+0

Возможный дубликат [Как проверить блокировку файлов?] (Http://stackoverflow.com/questions/1304/how-to-check-for-file-lock) – Plutonix

+0

Я не хочу знать, заперта. Я хочу получать уведомления, когда он НЕ заблокирован. – SuperJMN

+2

[https://social.msdn.microsoft.com/Forums/vstudio/en-US/dd1d86a8-b803-4425-bf84-db9a4b7c1d52/filesystemwatcher-for-locks-readwrite-lock-on-files?forum = csharpgeneral] (https://social.msdn.microsoft.com/Forums/vstudio/en-US/dd1d86a8-b803-4425-bf84-db9a4b7c1d52/filesystemwatcher-for-locks-readwrite-lock-on-files?forum= csharpgeneral) – esiprogrammer

ответ

1

Вы не сможете обойти метод проб и ошибок, т. Е. Попытаться открыть файл, поймать IOException, повторите попытку. Тем не менее, вы можете скрыть это безобразие в отдельный класс, например, так:

public class CustomWatcher 
{ 
    private readonly FileSystemWatcher watcher; 
    public event EventHandler<FileSystemEventArgs> CreatedAndReleased; 

    public CustomWatcher(string path) 
    { 
     watcher = new FileSystemWatcher(path, "*.jpg"); 
     watcher.Created += OnFileCreated; 
     watcher.EnableRaisingEvents = true; 
    } 

    private void OnFileCreated(object sender, FileSystemEventArgs e) 
    { 
     // Running the loop on another thread. That means the event 
     // callback will be on the new thread. This can be omitted 
     // if it does not matter if you are blocking the current thread. 
     Task.Run(() => 
     { 
      // Obviously some sort of timeout could be useful here. 
      // Test until you can open the file, then trigger the CreeatedAndReleased event. 
      while (!CanOpen(e.FullPath)) 
      { 
       Thread.Sleep(200); 
      } 
      OnCreatedAndReleased(e); 
     }); 
    } 

    private void OnCreatedAndReleased(FileSystemEventArgs e) 
    { 
     CreatedAndReleased?.Invoke(this, e); 
    } 

    private static bool CanOpen(string file) 
    { 
     FileStream stream = null; 
     try 
     { 
      stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.None); 
     } 
     catch (IOException) 
     { 
      return false; 
     } 
     finally 
     { 
      stream?.Close(); 
     } 
     return true; 
    } 
} 

Этот «сторож» может быть использован, как это:

var watcher = new CustomWatcher("path"); 
watcher.CreatedAndReleased += (o,e) => 
{ 
    // Now, your watcher has managed to open and close the file, 
    // so the camera is done with it. Obviously, any other application 
    // is able to lock it before this code manages to open the file. 
    var stream = File.OpenRead(e.FullPath); 
} 

Отказ от ответственности: CustomWatcher вероятно, должен быть IDisposable и распоряжаться FileSystemWatcher соответственно. Код просто показывает пример того, как достичь желаемой функциональности.

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

  • Нет связанных вопросов^_^