एक निर्देशिका की निगरानी करने के लिए FileSystemWatcher का उपयोग करना


101

मैं एक निर्देशिका की निगरानी करने के लिए एक विंडोज़ फ़ॉर्म एप्लिकेशन का उपयोग कर रहा हूं और इसमें गिरा फ़ाइलों को किसी अन्य निर्देशिका में स्थानांतरित कर रहा हूं।

फिलहाल यह फ़ाइल को किसी अन्य निर्देशिका में कॉपी कर देगा, लेकिन जब कोई अन्य फ़ाइल जोड़ी जाती है तो यह बिना किसी त्रुटि संदेश के समाप्त हो जाएगी। कभी-कभी यह तीसरे पर समाप्त होने से पहले दो फ़ाइलों की प्रतिलिपि बनाता है।

क्या यह इसलिए है क्योंकि मैं एक कंसोल ऐप के बजाय विंडोज फॉर्म एप्लिकेशन का उपयोग कर रहा हूं? क्या कोई ऐसा तरीका है जिससे मैं कार्यक्रम को समाप्त होने से रोक सकता हूं और निर्देशिका को देखता रह सकता हूं?

private void watch()
{
  this.watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                         | NotifyFilters.FileName | NotifyFilters.DirectoryName;
  watcher.Filter = "*.*";
  watcher.Changed += OnChanged;
  watcher.EnableRaisingEvents = true;
}

private void OnChanged(object source, FileSystemEventArgs e)
{
  //Copies file to another directory.
}

public void Dispose()
{
  // avoiding resource leak
  watcher.Changed -= OnChanged;
  this.watcher.Dispose();
}

जवाबों:


144

समस्या सूचना फ़िल्टर थी। कार्यक्रम एक फ़ाइल खोलने की कोशिश कर रहा था जो अभी भी नकल कर रहा था। मैंने LastWrite को छोड़कर सभी अधिसूचित फ़िल्टर हटा दिए हैं।

private void watch()
{
  FileSystemWatcher watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastWrite;
  watcher.Filter = "*.*";
  watcher.Changed += new FileSystemEventHandler(OnChanged);
  watcher.EnableRaisingEvents = true;
}

6
नमस्ते, मैं इस दृष्टिकोण का उपयोग कर रहा था, लेकिन जब मैं एक फ़ाइल की प्रतिलिपि बनाता हूं तो घटना दो बार उठाई जाती है: एक बार जब फ़ाइल खाली बनाई जाती है (प्रतिलिपि प्रारंभ होती है) और एक बार जब प्रतिलिपि समाप्त होती है। इस डुप्लिकेट किए गए ईवेंट से कैसे बचें, कोई भी फ़िल्टर बिना किसी कस्टम नियंत्रण के इसे संभाल सकता है?
डफाल्जमेमे

यदि मेरे आवेदन के लिए कुछ भी सार्थक दिखाई देता है, तो मैं दोनों घटनाओं की जांच करता हूं।
इफ्तिखारी

30

आपने फ़ाइल हैंडलिंग कोड की आपूर्ति नहीं की है, लेकिन मुझे लगता है कि आपने एक ही गलती की है जब हर कोई पहली बार ऐसा लिख ​​रहा है: फ़ाइल बनाते ही फ़ाइलेवर इवेंट को उठाया जाएगा। हालाँकि, फ़ाइल को समाप्त होने में कुछ समय लगेगा। उदाहरण के लिए 1 जीबी का फ़ाइल आकार लें। फ़ाइल किसी अन्य प्रोग्राम (Explorer.exe इसे कहीं से कॉपी करके) बनाई जा सकती है, लेकिन उस प्रक्रिया को पूरा करने में कुछ मिनट लगेंगे। ईवेंट को निर्माण समय पर उठाया गया है और आपको फ़ाइल की प्रतिलिपि तैयार होने के लिए प्रतीक्षा करने की आवश्यकता है।

आप लूप में इस फ़ंक्शन का उपयोग करके किसी फ़ाइल के तैयार होने की प्रतीक्षा कर सकते हैं ।


25

इसका कारण यह हो सकता है कि चौकीदार को एक विधि के रूप में स्थानीय चर के रूप में घोषित किया जाता है और विधि समाप्त होने पर इसे एकत्र किया जाता है। आपको इसे एक वर्ग के सदस्य के रूप में घोषित करना चाहिए। निम्नलिखित प्रयास करें:

FileSystemWatcher watcher;

private void watch()
{
  watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                         | NotifyFilters.FileName | NotifyFilters.DirectoryName;
  watcher.Filter = "*.*";
  watcher.Changed += new FileSystemEventHandler(OnChanged);
  watcher.EnableRaisingEvents = true;
}

private void OnChanged(object source, FileSystemEventArgs e)
{
  //Copies file to another directory.
}

18
watcherचर को जीवित रखा जाता है (कचरा एकत्र नहीं किया जाता है) क्योंकि वह परिवर्तित घटना के लिए सदस्यता लेता है।
12

1
मेरा मानना ​​है कि यह वास्तव में है क्योंकि EnableRaisingEvents को सेट किया गया है true। मुझे नहीं लगता कि सदस्य घटना संचालकों की स्थिति कचरा संग्रहण से है। मुझे लगता है कि EnableRaisingEvents के पास, जो मैं अनुकूल रूप से कह सकता हूं, इस मामले में एक विशेष व्यवहार है।
मटियास ग्रियोनी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.