2011-08-26 19 views
6

Đây là logic tôi đang cố gắng mã:FileSystemWatcher kích hoạt trước khi tệp được lưu - làm cách nào để bạn "tạm dừng" quá trình này?

Dịch vụ giám sát tệp .pptx trong thư mục. Nếu tệp đã thay đổi thực hiện chuyển đổi thành jpg. Sau đó thực hiện các tác vụ khác, sẽ được bổ sung sau.

Tôi đang sử dụng đối tượng thu thập tệp nhưng sẽ kích hoạt ngay sau khi tôi mở tệp, vì vậy tôi đã dừng quá trình bằng cách kiểm tra xem tệp có bị "khóa" hay không. Tôi nghĩ rằng một "trong khi bị khóa" vòng lặp sẽ làm các trick - nhưng không có. Dưới đây là nguyên mẫu mã giảm và tôi woiuld thích nếu bạn có thể nhìn vào nó cho thấy những gì tôi đang làm sai và/hoặc nếu có một cách tốt hơn để viết này cho một môi trường sản xuất. Tệp pptx có thể mở trong một thời gian dài.

namespace FileWatcherDemo 
{ 
    public class Program 
    { 

    static void Main(string[] args) 
    { 
     FileSystemWatcher fsWatcher = new FileSystemWatcher(); 
     fsWatcher.Path = @"e:\\"; 

     fsWatcher.NotifyFilter = NotifyFilters.LastWrite; 

     fsWatcher.Filter = "*.pptx"; 
     fsWatcher.Changed += new FileSystemEventHandler(fsWatcher_Changed); 
     //fsWatcher.Created += new FileSystemEventHandler(fsWatcher_Changed); 
     //fsWatcher.Deleted += new FileSystemEventHandler(fsWatcher_Changed); 
     //fsWatcher.Renamed += new RenamedEventHandler(fsWatcher_Changed); 
     fsWatcher.EnableRaisingEvents = true; 
     Console.ReadKey(); 
    }   

    static void fsWatcher_Changed(object sender, FileSystemEventArgs e) 
    { 
     try 
     { 
      while(!IsFileLocked()) 
      { 
       Console.WriteLine("Changed Event Fired"); 
       Microsoft.Office.Interop.PowerPoint.Application app = new Microsoft.Office.Interop.PowerPoint.Application(); 
       Presentation pptPresentation = app.Presentations.Open(@"e:\\HowTo.pptx", MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse); 

       pptPresentation.SaveAs(@"e:\\Output", PpSaveAsFileType.ppSaveAsJPG, MsoTriState.msoFalse); 
       pptPresentation.Close(); 
      } 
     } 
     catch (Exception ex) 
     { 
      using (StreamWriter w = File.AppendText(@"e:\\ErrorLog.txt")) 
      { 
       Log(ex.Message.ToString(), w); 
       Log(ex.StackTrace.ToString(), w); 

       w.Close(); 
      } 
     } 

     Console.ReadKey(); 
    } 

    static bool IsFileLocked() 
    { 
     FileStream fs = null; 
     FileInfo file = new FileInfo(@"e:\\HowTo.pptx");    

     try 
     { 
      fs = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); 
     } 
     catch (IOException) 
     { 
      return true; 
     } 
     finally 
     { 
      if(fs != null) 
       fs.Close(); 
     } 
     return false; 
    } 

    public static void Log(string LogMessage, TextWriter w) 
    { 
     w.Write("\r\nLog Entry: "); 
     w.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString()); 
     w.WriteLine(" :"); 
     w.WriteLine(" {0}", LogMessage.ToString()); 
     w.WriteLine("------------------------------------------"); 

     w.Flush(); 
    } 
} 

}

Trả lời

2

Dưới đây là một ý tưởng khác: Khi FileSystemWatcher phát hiện sự thay đổi (Bạn nói nó cháy ngay lập tức các tập tin được mở ra) ghi lại LastModifiedTime của tập tin và giữ vòng lặp cho đến khi LastModifiedTime trong những thay đổi tập tin (Giả sử LastModifiedTime chỉ được ghi khi tệp được lưu - Tôi không biết khi nào điều này thực sự được thực hiện) và sau đó thực hiện quy trình chuyển đổi sang JPG của bạn.

EDIT

Thêm mã mà phải chứng minh làm thế nào để theo dõi khi một tập tin đã được sửa đổi:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Thread t = new Thread(()=> DoTest()); 
     t.Start(); 

     Console.WriteLine("Waiting..."); 
     Console.ReadKey(); 
    } 

    private static void DoTest() 
    { 
     FileSystemWatcher fsw = new FileSystemWatcher("C:\\"); 
     fsw.Filter = "*.txt"; 
     fsw.Changed += new FileSystemEventHandler(fsw_Changed); 
     fsw.Deleted += new FileSystemEventHandler(fsw_Deleted); 
     fsw.Renamed += new RenamedEventHandler(fsw_Renamed); 
     fsw.Created += new FileSystemEventHandler(fsw_Created); 
     fsw.EnableRaisingEvents = true; 
    } 

    static void fsw_Created(object sender, FileSystemEventArgs e) 
    { 
     FileInfo fi = new FileInfo(e.FullPath); 
     Console.WriteLine("File Created: "+e.FullPath); 
     Console.WriteLine("Creation Time: " + fi.CreationTime.ToLongTimeString()); 
     Console.WriteLine("Last Access Time: " + fi.LastAccessTime.ToLongTimeString()); 
     Console.WriteLine("Last Write Time: " + fi.LastWriteTime.ToLongTimeString()); 
     Console.WriteLine("Length: " + fi.Length); 

    } 

    static void fsw_Renamed(object sender, RenamedEventArgs e) 
    { 
     FileInfo fi = new FileInfo(e.FullPath); 
     Console.WriteLine("File Renamed: "+e.FullPath); 
     Console.WriteLine("Creation Time: " + fi.CreationTime.ToLongTimeString()); 
     Console.WriteLine("Access Time: " + fi.LastAccessTime.ToLongTimeString()); 
     Console.WriteLine("Last Write Time: " + fi.LastWriteTime.ToLongTimeString()); 
     Console.WriteLine("Length: " + fi.Length); 
    } 

    static void fsw_Deleted(object sender, FileSystemEventArgs e) 
    { 
     FileInfo fi = new FileInfo(e.FullPath); 
     Console.WriteLine("File Deleted: "+e.FullPath); 
     Console.WriteLine("Creation Time: " + fi.CreationTime.ToLongTimeString()); 
     Console.WriteLine("Last Access Time: " + fi.LastAccessTime.ToLongTimeString()); 
     Console.WriteLine("Last Write Time: " + fi.LastWriteTime.ToLongTimeString()); 

    } 

    static void fsw_Changed(object sender, FileSystemEventArgs e) 
    { 
     FileInfo fi = new FileInfo(e.FullPath); 
     Console.WriteLine("File Changed: "+e.FullPath); 
     Console.WriteLine("Creation Time: " + fi.CreationTime.ToLongTimeString()); 
     Console.WriteLine("Last Access Time: " + fi.LastAccessTime.ToLongTimeString()); 
     Console.WriteLine("Last Write Time: " + fi.LastWriteTime.ToLongTimeString()); 
     Console.WriteLine("Length: " + fi.Length); 
    } 
} 
+0

Vâng, dislplays LastAccesTime FileInfo của thực sự họ thời gian mà không phải là thời gian hiện tại và đó là những gì tôi muốn. Tuy nhiên, không có thuộc tính nào theo dõi thay đổi. Làm thế nào để bạn kiểm tra cho điều đó? Cảm ơn. – Risho

+0

@Risho Tôi không biết tại sao bạn nói rằng không có tài sản nào theo dõi thay đổi. Tôi đang chỉnh sửa câu trả lời của mình bằng mã mẫu. Tôi đã có thể theo dõi sự kiện thay đổi trên một tệp và thời gian DID thực sự tăng lên mỗi khi tệp được sửa đổi. – Icarus

+0

vì tất cả các phương pháp fsw_ đều kích hoạt ngay khi tôi nhấp vào tệp không khi tệp được lưu. Tôi phải tính đến thực tế là tệp có thể mở trong nhiều giờ. – Risho

1

Có một số lượng lớn của logic nhu cầu của bạn phải làm gì để làm cho FileSystemWatcher phù hợp cho mã cấp sản xuất.

  • Bạn muốn giữ lại xử lý sự kiện rất nhẹ, chỉ cần xếp hàng rằng một cái gì đó đã xảy ra và sau đó xử lý nó sau này.

  • Sử dụng bộ hẹn giờ (System.Threading là tốt nhất) để xử lý hàng đợi với độ trễ 1000ms khi bạn nhận được sự kiện, dừng/khởi động bộ hẹn giờ.

  • Kiểm tra hàng đợi cho nhiều sự kiện cho cùng một tệp, ví dụ: một chương trình có thể tạo một tập tin và sau đó xóa nó một lần nữa.

Edit: tôi chỉ làm một tìm kiếm nhanh Google và tìm thấy một bài báo và mẫu mã mà sẽ giúp bạn có được 90% đó.

http://csharp-codesamples.com/2009/02/file-system-watcher-and-large-file-volumes/

http://web.archive.org/web/20120814142626/http://csharp-codesamples.com/2009/02/file-system-watcher-and-large-file-volumes/

Chỉnh sửa 2: Chỉ cần đọc lại câu hỏi của bạn. Lời khuyên ở trên vẫn được áp dụng, tuy nhiên một vài điều hơn để bạn có thể làm để giải quyết vấn đề của bạn:

  • Powerpoint, như ứng dụng văn phòng khác, tạo ra một tập tin tạm thời ẩn với một tiền tố ~.

  • Kiểm tra tem thời gian sửa đổi tệp.Khi bạn lần đầu tiên nhận thấy một tệp đã thay đổi, hãy lưu thời gian sửa đổi và so sánh với tệp đó vào lần tiếp theo tệp được thay đổi.

  • Có một thuộc tính cờ của trình theo dõi hệ thống tệp mà bạn sẽ cần phải đặt để nhận các thay đổi về thời gian sửa đổi.

Hy vọng tất cả điều này giúp ...

+0

Liên kết bị hỏng. – SuperJMN

+0

@SuperJMN, cảm ơn bạn đã báo cáo. Tôi đã sửa liên kết bằng một bản sao từ kho lưu trữ. – Dennis

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