2010-09-01 28 views
8

मैं फ़ाइल सिस्टम संशोधित या हटाए जाने पर जांचने के लिए FileSystemWatcher का उपयोग कर रहा हूं, लेकिन मुझे आश्चर्य है कि किसी अन्य एप्लिकेशन द्वारा फ़ाइल को पढ़ने के दौरान जांचने का कोई तरीका है या नहीं।फ़ाइल का पता लगाएं सी #

उदाहरण: मेरे पास मेरे हार्डड्राइव पर फ़ाइल C: \ test.txt है और मैं FileSystemWatcher का उपयोग कर इसे देख रहा हूं। एक और कार्यक्रम (मेरे नियंत्रण में नहीं) उस फ़ाइल को पढ़ने के लिए जाता है; मैं उस घटना को पकड़ना चाहता हूं और यदि संभव हो, तो जांचें कि कौन सा प्रोग्राम फ़ाइल पढ़ रहा है, उसके बाद फ़ाइल की सामग्री को संशोधित करें।

+1

यह एक अजीब आवश्यकता की तरह लगता है। क्या आप विस्तार कर सकते हैं कि आपका अंतिम लक्ष्य थोड़ा और अधिक है। – luke

+0

@luke - मैं क्या करना चाहता हूं फ़ाइल के एक हिस्से को एन्क्रिप्ट करना है, लेकिन जब एक वेब एप्लिकेशन (जिस पर मेरा नियंत्रण नहीं है) उस फ़ाइल को पढ़ने के लिए जाता है, तो मैं इसके लिए एन्क्रिप्टेड हिस्से को डिक्रिप्ट कर दूंगा। –

+0

यह हल करने के लिए एक बेहतर तरीका प्रतीत होता है, यह केवल अधिक बढ़िया अनाज नियंत्रण नियंत्रण स्थापित करना होगा ताकि केवल वेब ऐप (और आपका ऐप) फ़ाइल को पढ़ सके, तो आपको इसे एन्क्रिप्ट करना पड़ेगा। – luke

उत्तर

4

ऐसा लगता है जैसे आप जब अपने लॉग फ़ाइल बाह्य उस प्रभाव के लिए कुछ पढ़ा है, या अपने लॉग फ़ाइल के लिए लिखना चाहते हैं। यदि ऐसा है, तो NotifyFilters मान, LastAccess है। सुनिश्चित करें कि यह आपके FileSystemWatcher.NotifyFilter प्रॉपर्टी में झंडे में से एक के रूप में सेट है। अंतिम पहुंच समय में परिवर्तन तब फ़ाइल सिस्टम सिस्टम पर परिवर्तित ईवेंट को आग लगा देगा।

वर्तमान में, FileSystemWatcher आप सीधे पढ़ने और एक परिवर्तन के बीच अंतर करने की अनुमति नहीं है; वे दोनों LastAccess पर "परिवर्तन" के आधार पर परिवर्तित घटना को आग लगाते हैं। इसलिए, बड़ी संख्या में फाइलों को पढ़ने के लिए देखना असंभव होगा। हालांकि, आपको पता है कि आप कौन सी फाइल देख रहे हैं, इसलिए यदि आपके पास उस फ़ाइल के लिए FileInfo ऑब्जेक्ट था, और FileSystemWatcher ने अपनी बदली हुई घटना को निकाल दिया, तो आप एक नया प्राप्त कर सकते हैं और LastAccessTime मानों की तुलना कर सकते हैं। यदि एक्सेस समय बदल गया है, और LastWriteTime नहीं था, तो आपकी फ़ाइल केवल पढ़ी जा रही है।

अब, सबसे सरल शब्दों में, जब आप इसे पढ़ रहे हों तो फ़ाइल में बदलावों को तुरंत दूसरे ऐप में दिखाया नहीं जा रहा है, न ही आप "पहले वहां पहुंचने" में सक्षम होने जा रहे हैं, फ़ाइल को लॉक करें और इसे देखने से पहले इसे लिखो। इसलिए, आप FileSystemWatcher को एक पठन अनुरोध को "अवरुद्ध" करने के लिए उपयोग नहीं कर सकते हैं और उस सामग्री को दिखा सकते हैं जिसे आप देखना चाहते हैं। एक अन्य तरीका का उपयोगकर्ता एकमात्र तरीका देख सकता है जो आपने अभी लिखा है, यदि एप्लिकेशन फ़ाइल को भी देख रहा है और फ़ाइल को फिर से लोड करता है। इससे एक और बदली हुई घटना को आग लग जाएगी, जिससे एक अनंत लूप होता है जब तक कि अन्य एप्लिकेशन फ़ाइल को फिर से लोड करना जारी रखता है।

तुम भी पढ़ने और लिखने के लिए एक परिवर्तित ईवेंट के मिल जाएगा। किसी टेक्स्ट एडिटर में फ़ाइल खोलना (वस्तुतः कोई भी करेगा), कुछ बदलाव कर रहा है, फिर सहेजने पर दो बदले गए ईवेंट होंगे यदि आप अंतिम एक्सेस समय में बदलाव की तलाश में हैं। संपादक द्वारा फ़ाइल खोले जाने पर पहला व्यक्ति बंद हो जाएगा; उस समय, आप यह बताने में सक्षम नहीं होंगे कि एक लेखन होगा, इसलिए यदि आप फ़ाइल को शुद्ध केवल पढ़ने के लिए देख रहे हैं तो आप एसओएल हैं।

-2

एक छोटी सी snippet है कि मैं का पता लगाने जब किसी अन्य प्रक्रिया एक ताला है के लिए उपयोगी पाया:

static bool IsFileUsedbyAnotherProcess(string filename) 
     { 
      try 
      { 
       using(var file = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.None)) 
       { 
       } 
      } 
      catch (System.IO.IOException exp) 
      { 
       return true; 
      } 
      return false; 
     } 
+3

केवल तभी काम करता है जब अन्य एप्लिकेशन ने इसे लिखने के लिए बंद कर दिया हो। पढ़ने के लिए फ़ाइल खोलना जरूरी नहीं है। – KeithS

+3

Egad! यह फ़ंक्शन तब तक खुला रहता है जब तक कि यह कचरा-संग्रह न हो जाए, जिसका अर्थ है कि कोई भी इसे सक्षम किए बिना इसे खोल सकता है। – Gabe

+2

और कौन फ़ाइल को बंद करता है। ओपन() यहां? – kofucii

2

सबसे आसान तरीका है मैं के बारे में सोच सकते हैं यह करने के लिए एक टाइमर (System.Threading.Timer) जिसका कॉलबैक चेकों के साथ हो सकता है और पिछले

System.IO.File.GetLastAccessTime(path) 

कुछ की तरह (शायद के साथ संग्रहीत करता हैं थोड़ा और ताला ...)

public class FileAccessWatcher 
{ 

public Dictionary<string, DateTime> _trackedFiles = new Dictionary<string, DateTime>(); 

private Timer _timer; 

public event EventHandler<EventArgs<string>> FileAccessed = delegate { }; 

public FileAccessWatcher() 
{ 
    _timer = new Timer(OnTimerTick, null, 500, Timeout.Infinite); 
} 

public void Watch(string path) 
{ 
    _trackedFiles[path] = File.GetLastAccessTime(path); 
} 

public void OnTimerTick(object state) 
{ 
    foreach (var pair in _trackedFiles.ToList()) 
    { 
     var accessed = File.GetLastAccessTime(pair.Key); 
     if (pair.Value != accessed) 
     { 
      _trackedFiles[pair.Key] = accessed; 
      FileAccessed(this, new EventArgs<string>(pair.Key)); 
     } 
    } 

    _timer.Change(500, Timeout.Infinite); 
} 
} 
2

वहाँ SysInternals 'कार्यक्रम FileMon ... यह सिस्टम में हर फ़ाइल पहुँच का पता लगा सकते है। यदि आप इसका स्रोत पा सकते हैं, और समझ सकते हैं कि यह Win32 हुक का उपयोग करता है, तो आप उन कार्यों को सी # में मार्शल कर सकते हैं और जो चाहते हैं उसे प्राप्त कर सकते हैं।

0

हाँ, फ़ाइल सिस्टम फ़िल्टर ड्राइवर का उपयोग करके आप सभी पढ़ने के अनुरोधों को पकड़ सकते हैं, उनका विश्लेषण कर सकते हैं और डेटा को पढ़ने के विकल्प भी बदल सकते हैं। ऐसे ड्राइवर का विकास संभव है, लेकिन बहुत समय लेने वाला और जटिल है। हम CallbackFilter नामक एक उत्पाद की पेशकश करते हैं, जिसमें ड्राइवर का उपयोग करने के लिए तैयार है और आपको उपयोगकर्ता-मोड में अपने फ़िल्टरिंग व्यवसाय तर्क को लागू करने देता है।

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