2010-02-09 34 views
10

Tôi có trình theo dõi tệp sẽ kích hoạt sự kiện khi tệp được sửa đổi. Tôi muốn đọc từ tệp đó khi khóa đã bị xóa. Hiện tại tôi chỉ đang cố gắng mở tệp khi sự kiện được kích hoạt, khi một tệp lớn đang được sao chép, khóa tệp vẫn bật trong một thời gian sau khi các sự kiện đã được gửi, ngăn tệp mở để truy cập đọc.Trình kích hoạt FileSystemWatcher cho luồng phim mở

Mọi đề xuất?

Trả lời

6

Điều này thực sự là một chút của một doozie, trừ khi không gian vấn đề đã thay đổi đáng kể kể từ khi tôi cuối cùng đã phải đối phó với nó.

Cách dễ nhất là chỉ cần cố mở tệp, bắt kết quả IOException và nếu tệp bị khóa, hãy thêm nó vào hàng đợi để kiểm tra sau. Bạn không thể chỉ xử lý mọi tệp có trong vì có tất cả các loại trường hợp nhiều sự kiện sẽ được tạo cho cùng một tệp, do đó, thiết lập vòng lặp thử lại trên mỗi sự kiện nhận được có thể biến thành thảm họa, nhanh chóng. Bạn cần phải xếp hàng chúng thay vào đó và kiểm tra hàng đợi tại một khoảng thời gian thường xuyên.

Đây là một mẫu lớp cơ bản mà sẽ giúp bạn ra ngoài với vấn đề này:

public class FileMonitor : IDisposable 
{ 
    private const int PollInterval = 5000; 

    private FileSystemWatcher watcher; 
    private HashSet<string> filesToProcess = new HashSet<string>(); 
    private Timer fileTimer; // System.Threading.Timer 

    public FileMonitor(string path) 
    { 
     if (path == null) 
      throw new ArgumentNullException("path"); 

     watcher = new FileSystemWatcher(); 
     watcher.Path = path; 
     watcher.NotifyFilter = NotifyFilters.FileName; 
     watcher.Created += new FileSystemEventHandler(FileCreated); 
     watcher.EnableRaisingEvents = true; 

     fileTimer = new Timer(new TimerCallback(ProcessFilesTimer), 
      null, PollInterval, Timeout.Infinite); 
    } 

    public void Dispose() 
    { 
     fileTimer.Dispose(); 
     watcher.Dispose(); 
    } 

    private void FileCreated(object source, FileSystemEventArgs e) 
    { 
     lock (filesToProcess) 
     { 
      filesToProcess.Add(e.FullPath); 
     } 
    } 

    private void ProcessFile(FileStream fs) 
    { 
     // Your code here... 
    } 

    private void ProcessFilesTimer(object state) 
    { 
     string[] currentFiles; 
     lock (filesToProcess) 
     { 
      currentFiles = filesToProcess.ToArray(); 
     } 
     foreach (string fileName in currentFiles) 
     { 
      TryProcessFile(fileName); 
     } 
     fileTimer.Change(PollInterval, Timeout.Infinite); 
    } 

    private void TryProcessFile(string fileName) 
    { 
     FileStream fs = null; 
     try 
     { 
      FileInfo fi = new FileInfo(fileName); 
      fs = fi.OpenRead(); 
     } 
     catch (IOException) 
     { 
      // Possibly log this error 
      return; 
     } 

     using (fs) 
     { 
      ProcessFile(fs); 
     } 

     lock (filesToProcess) 
     { 
      filesToProcess.Remove(fileName); 
     } 
    } 
} 

(Lưu ý - Tôi nhớ lại này từ bộ nhớ ở đây nên nó có thể không được hoàn hảo - cho tôi biết nếu đó là lỗi .)

+0

Tốt, đây là những gì tôi đã đi cùng trong khi chờ đợi. Tôi đã sử dụng một thời gian chờ và chờ đợi một lần nữa, tôi đã hy vọng có một cái gì đó thanh lịch hơn, nhưng oh tốt;) (Cảm ơn một triệu vì đã nỗ lực để trả lời tuyệt vời) – Matthew

Các vấn đề liên quan