2010-11-25 8 views
5

मैं एक .NET अनुप्रयोग विकसित कर रहा हूं, जहां मैं FileSystemWatcher क्लास का उपयोग कर रहा हूं और फ़ोल्डर में इसके निर्मित ईवेंट को संलग्न कर रहा हूं। मुझे इस घटना पर कार्रवाई करना है (यानी किसी अन्य स्थान पर फ़ाइल कॉपी करें)। जब मैं संलग्न घड़ी फ़ोल्डर में एक बड़ा आकार डाल रहा हूं तो ईवेंट तुरंत उठाया गया है, यहां तक ​​कि फाइल कॉपी प्रक्रिया अभी भी पूरी नहीं हुई है। मैं इसे file.open विधि से जांचना नहीं चाहता हूं।सी # FileSystemWatcher, फ़ाइल फ़ोल्डर को पूरी तरह से कॉपी फ़ोल्डर में कैसे कॉपी किया जाए

क्या कोई तरीका यह सूचित करता है कि मेरी फ़ाइल कॉपी प्रक्रिया घड़ी फ़ोल्डर में पूरी हो चुकी है और फिर मेरी घटना आग लग गई है।

+0

मैं एक ही मुद्दा था, और इसके अलावा में FileSystemWatcher कभी कभी मैं –

उत्तर

1

आप संशोधित घटना के लिए सुन सकते हैं, और एक टाइमर शुरू कर सकते हैं। यदि संशोधित घटना दोबारा उठाई जाती है, तो टाइमर रीसेट करें। जब टाइमर संशोधित घटना के बिना एक निश्चित मूल्य तक पहुंच गया है तो आप प्रतिलिपि करने का प्रयास कर सकते हैं। फिल्टर

myWatcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite; 
0

प्रयास करें, और यह इस तरह से हल:

  1. FileSystemWatcher सेट सूचित करने के लिए जब फ़ाइलें और बनाई गई हैं, जब वे संशोधित कर रहे हैं ।
  2. जब कोई सूचना आती है:

    ए। यदि इस फ़ाइल नाम के लिए कोई टाइमर सेट नहीं है (नीचे देखें), एक उपयुक्त अंतराल में समाप्त होने के लिए टाइमर सेट करें (मैं आमतौर पर 1 सेकंड का उपयोग करता हूं)।

    बी। यदि इस फ़ाइल नाम के लिए टाइमर सेट है, तो टाइमर रद्द करें और एक ही अंतराल में समाप्त होने के लिए एक नया सेट करें।

जब एक टाइमर समाप्त हो रहा है, आप जानते हैं कि संबद्ध फ़ाइल बना दिया गया है या संशोधित और समय अंतराल के लिए अछूता रहा है। इसका मतलब है कि कॉपी/संशोधित संभवतः किया गया है और अब आप इसे संसाधित कर सकते हैं।

+0

यह काम नहीं करेगा fireing घटना नहीं मिलता है सही ढंग से विंडोज 7 में काम करने के लिए लगता है नहीं है। कार्यक्रम कई बार उठाया जाएगा (एक बार फाइल लिखने के दौरान प्रत्येक लेखन पहुंच के लिए), और आपके पास यह बताने का कोई तरीका नहीं है कि क्या वह लिखना ऑपरेशन पिछली बार कॉपी पूरा करता है या नहीं। – gstercken

+0

मैं जाँच करता है, तो फ़ाइल घटना में लेखन पहुँच है, और प्रतिलिपि समाप्त करना तय है या नहीं –

2

मैं ठीक उसी समस्या पड़ा है स्थापित करने के लिए

+0

तुम मुझे अपना टाइमर कोड – user446526

+0

आप यहाँ कुछ पोस्ट कर सकते हैं साझा करें सकता है? धन्यवाद – Poorna

+0

@ प्यूमा: कोड के इस टुकड़े के लिए यह संभव नहीं है, क्षमा करें। – Jon

3

यह वास्तव में एक बहुत बेकार है कि FileSystemWatcher (और अंतर्निहित ReadDirectoryChangesW एपीआई) कोई रास्ता नहीं प्रदान करते ही सूचना प्राप्त करने के लिए जब एक नई फ़ाइल किया गया है पूरी तरह से बनाया।

इस के आसपास सबसे अच्छा और सबसे सुरक्षित तरीका है कि मैं (और कहा कि टाइमर पर निर्भर नहीं करता) अब तक का सामना करना पड़ा इस प्रकार है:

बनाया गया ईवेंट प्राप्त करने पर, एक धागा शुरू कि, एक में लूप, जांचता है कि फ़ाइल अभी भी लॉक है (एक उपयुक्त पुनः प्रयास अंतराल और अधिकतम पुनः प्रयास गिनती का उपयोग कर)। यह जांचने का एकमात्र तरीका है कि फ़ाइल लॉक है या नहीं, इसे अनन्य एक्सेस के साथ खोलने की कोशिश कर रहा है: यदि यह सफल होता है (IOException फेंक नहीं रहा है), तो फ़ाइल प्रतिलिपि बनाई जाती है, और आपका धागा एक उचित ईवेंट (उदा। FileCopyCompleted) बढ़ा सकता है।

1

मैं Changed - और Renamed की सदस्यता लेता हूं - IVExceptions को पकड़ने के लिए प्रत्येक Changed पर फ़ाइल का नाम बदलने का प्रयास करें। अगर नाम सफल हो जाता है, तो कॉपी समाप्त हो गई है और Rename -वेन्ट केवल एक बार निकाल दिया जाता है।

this.watcher.Created += (s, e) => 
{ 
    if (!this.seen.ContainsKey(e.FullPath) 
     || (DateTime.Now - this.seen[e.FullPath]) > this.seenInterval) 
    { 
     this.seen[e.FullPath] = DateTime.Now; 
     ThreadPool.QueueUserWorkItem(
      this.WaitForCreatingProcessToCloseFileThenDoStuff, e.FullPath); 
    } 
}; 

जहां this.seen एक Dictionary<string, DateTime> और this.seenInterval एक TimeSpan है: FileSystemWatcher साथ

1

तीन मुद्दों, पहला यह है कि यह नकली निर्माण की घटनाओं से बाहर भेजने ताकि आप की तरह कुछ के साथ उस के लिए जाँच कर सकते हैं।

इसके बाद, आप फ़ाइल बनाने वाला इसे (इस मुद्दे को सवाल में उठाया) लेखन समाप्त करने के लिए के लिए चारों ओर इंतजार करना। और, तीसरा, आपको सावधान रहना चाहिए क्योंकि कभी-कभी फ़ाइल निर्माण ईवेंट को FileNotFoundException दिए बिना फ़ाइल को खोला जा सकता है, लेकिन इससे पहले कि आप इसे पकड़ सकें, इसे FileNotFoundException भी प्रदान किया जा सकता है।

private void WaitForCreatingProcessToCloseFileThenDoStuff(object threadContext) 
{ 
    // Make sure the just-found file is done being 
    // written by repeatedly attempting to open it 
    // for exclusive access. 
    var path = (string)threadContext; 
    DateTime started = DateTime.Now; 
    DateTime lastLengthChange = DateTime.Now; 
    long lastLength = 0; 
    var noGrowthLimit = new TimeSpan(0, 5, 0); 
    var notFoundLimit = new TimeSpan(0, 0, 1); 

    for (int tries = 0;; ++tries) 
    { 
     try 
     { 
      using (var fileStream = new FileStream(
       path, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) 
      { 
       // Do Stuff 
      } 

      break; 
     } 
     catch (FileNotFoundException) 
     { 
      // Sometimes the file appears before it is there. 
      if (DateTime.Now - started > notFoundLimit) 
      { 
       // Should be there by now 
       break; 
      } 
     } 
     catch (IOException ex) 
     { 
      // mask in severity, customer, and code 
      var hr = (int)(ex.HResult & 0xA000FFFF); 
      if (hr != 0x80000020 && hr != 0x80000021) 
      { 
       // not a share violation or a lock violation 
       throw; 
      } 
     } 

     try 
     { 
      var fi = new FileInfo(path); 
      if (fi.Length > lastLength) 
      { 
       lastLength = fi.Length; 
       lastLengthChange = DateTime.Now; 
      } 
     } 
     catch (Exception ex) 
     { 
     } 

     // still locked 
     if (DateTime.Now - lastLengthChange > noGrowthLimit) 
     { 
      // 5 minutes, still locked, no growth. 
      break; 
     } 

     Thread.Sleep(111); 
    } 

आप, ज़ाहिर है, अपने खुद के समय समाप्ति सेट कर सकते हैं। यह कोड 5 मिनट के लिए पर्याप्त समय छोड़ देता है। अनुरोध किए जाने पर रीड कोड में थ्रेड से बाहर निकलने के लिए ध्वज भी होगा।

0

इस उत्तर देर से एक सा है, लेकिन मैं स्रोत प्रक्रिया प्राप्त होता यदि संभव हो तो बड़ी फ़ाइल या फ़ाइलों के बाद एक छोटे से मार्कर फाइल कॉपी और उस पर FileWatcher उपयोग करने के लिए।

संबंधित मुद्दे