2012-02-21 16 views
12

खोलने से संबंधित अपवादों का मोर ठीक है, इसलिए मैंने इस प्रश्न के उत्तर के लिए कई जगहों पर खोज की है, लेकिन अगर मैं कुछ स्पष्ट याद करता हूं तो मैं किसी भी लिंक के लिए खुला हूं।फ़ाइलस्ट्रीम

मैं किसी विशेष फ़ाइल को खोलने का प्रयास करते समय उपयोगकर्ता को उचित त्रुटि संदेश बनाने में रूचि रखता हूं, लेकिन किसी भी कारण से प्रोग्राम उस फ़ाइल तक नहीं पहुंच सकता है। मैं निम्नलिखित मामलों के बीच अंतर करना चाहता हूं:

  • फ़ाइल को दूसरी प्रक्रिया द्वारा लॉक किया गया था जैसे कि यह प्रक्रिया इसे लिख नहीं सकती है।
  • उपयोगकर्ता के पास फ़ाइल में लिखने के लिए उचित पहुंच विशेषाधिकार नहीं हैं (जैसे, उनके उपयोगकर्ता अनुमतियां, जैसा कि विंडोज एक्सप्लोरर में फ़ाइल के लिए प्रॉपर्टी स्क्रीन में देखा गया है, उपयोगकर्ता लिखने की अनुमति न दें)
  • फ़ाइल को फ़ाइल तक पहुंचने के लिए "उन्नत" अनुमति की आवश्यकता है।

मैं एक फ़ाइलस्ट्रीम ऑब्जेक्ट का उपयोग कर रहा हूं। मैंने msdn documentation for instantiating a FileStream पर देखा है, और यह बिल्कुल स्पष्ट नहीं है कि अपवाद उपरोक्त के लिए क्या करता है, और उनके बीच अंतर कैसे करें। मैं मानता हूं कि विंडोज प्रोग्रामिंग के साथ मेरा अनुभव सीमित है, इसलिए मुझे कुछ स्पष्ट याद आ रही है। अगर माफी माँगती है तो।

+1

क्या पिछले 2 मामलों के बीच आप कोई अंतर दिखाना चाहते हैं? मैं कल्पना करता हूं (हालांकि साबित नहीं हुआ है) कि वे दोनों 'सुरक्षा अपवाद' फेंक देंगे जहां पहला मामला 'आईओएक्सप्शन' फेंक देगा। –

+0

@ एम। बाबाकॉक: कुछ मायनों में, पिछले दो मामले बहुत अलग नहीं हैं। हालांकि, उपयोगकर्ता को फ़ाइल में पहुंच प्राप्त करने के लिए (सामान्य रूप से) बहुत अलग चीज़ें करना पड़ता है। दूसरे मामले के लिए, उन्हें अनुरोध करना होगा कि कोई अन्य उपयोगकर्ता उन्हें अनुमति दे। तीसरे मामले के लिए, उन्हें "व्यवस्थापक के रूप में चलाएं" या शायद "प्रोग्राम फ़ाइलें" निर्देशिका से फ़ाइल को स्थानांतरित करने की आवश्यकता है (हालांकि यह वहां क्यों होगा जहां मुझे नहीं पता)। मैं उपयोगकर्ता को यह जानने में मदद करना चाहता हूं कि फ़ाइल तक पहुंच प्राप्त करने के लिए उन्हें क्या करना है। – skybluecodeflier

+0

एक बार फिर, मैं अपनी पिछली टिप्पणी में विंडोज ओएस की अपनी अज्ञानता दिखा रहा हूं- अगर मेरी व्याख्या गलत है तो मैं सुधार के लिए खुला हूं। – skybluecodeflier

उत्तर

5

यहाँ आप क्या कर सकते हैं:

1) यदि आप से पहले फ़ाइल के लिए उपयोग करने के अधिकार हैं अपनी फ़ाइल को एक्सेस करने का प्रयास आप परीक्षण कर सकता है। this SO thread से, यहां एक विधि है जो उपयोगकर्ता को Write अधिकार (यानी जब फ़ाइल -> संपत्ति -> सुरक्षा पर राइट-क्लिक करते हैं) सही होनी चाहिए। यह नियत करने के नहीं पहुंच विशेषाधिकार के लिए अपनी बात (2) को शामिल किया गया है (ध्यान दें कुछ और अधिक मजबूत/त्रुटि प्रूफ है कि वहाँ शायद नीचे दिए गए कोड से यह जानकारी प्राप्त करने है):

public static bool HasWritePermissionOnFile(string path) 
{ 
    bool writeAllow = false; 
    bool writeDeny = false; 

    FileSecurity accessControlList = File.GetAccessControl(path); 
    if (accessControlList == null) 
    { 
     return false; 
    } 

    var accessRules = accessControlList.GetAccessRules(true, true, typeof(SecurityIdentifier)); 
    if (accessRules == null) 
    { 
     return false; 
    } 

    foreach (FileSystemAccessRule rule in accessRules) 
    { 
     if ((FileSystemRights.Write & rule.FileSystemRights) != FileSystemRights.Write) 
     { 
      continue; 
     } 

     if (rule.AccessControlType == AccessControlType.Allow) 
     { 
      writeAllow = true; 
     } 
     else if (rule.AccessControlType == AccessControlType.Deny) 
     { 
      writeDeny = true; 
     } 
    } 

    return writeAllow && !writeDeny; 
} 

2) अपने FileStream का दृष्टांत करने की कोशिश करो , और पकड़ अपवाद:

try 
{ 
    string file = "..."; 
    bool hasWritePermission = HasWritePermissionOnFile(file); 
    using (FileStream fs = new FileStream(file, FileMode.Open)) 
    { 
    } 
} 
catch (UnauthorizedAccessException ex) 
{ 
    // Insert some logic here 
} 
catch (FileNotFoundException ex) 
{ 
    // Insert some logic here 
} 
catch (IOException ex) 
{ 
    // Insert some logic here 
} 

आपके मामले में (3) (फ़ाइल की आवश्यकता होती), UnauthorizedAccessException फेंक दिया है।

आपके मामले में (1) (फ़ाइल किसी अन्य प्रक्रिया द्वारा लॉक है), IOException फेंक दिया गया है। इसके बाद आप अधिक जानकारी के लिए अपवाद के HRESULT जाँच कर सकते हैं:

catch (IOException ex) 
{ 
    // Gets the HRESULT 
    int hresult = Marshal.GetHRForException(ex); 

    // See http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx 
    // for system error code 
    switch (hresult & 0x0000FFFF) 
    { 
     case 32: //ERROR_SHARING_VIOLATION 
      Console.WriteLine("File is in use by another process"); 
      break; 
    } 
} 

अब आप अपने 3 उपयोग के मामलों भेद करने में सक्षम होना चाहिए।

+0

हम्म। यह समझ में आता है- मैं इसका परीक्षण करूंगा। हालांकि मुझे नहीं लगता कि मैं पूरी तरह से समाधान 1 में भरोसा कर पाऊंगा जो आपने रेस की स्थिति की संभावना के कारण यहां निर्दिष्ट किया है। यही है, ए) मेरी प्रक्रिया यह देखने के लिए जांचती है कि क्या यह फ़ाइल तक पहुंच सकता है, बी) कुछ अन्य प्रक्रिया फ़ाइल (या परिवर्तन अनुमतियां इत्यादि) खोलती है, सी) मेरी प्रक्रिया फाइल खोलने की कोशिश करती है और विफल/क्रैकी/आदि हो जाती है। – skybluecodeflier

+0

वास्तव में यदि उपयोगकर्ता 'हैसवाइटप्रमिशनऑनफ़ाइल' चेक और 'नई फ़ाइलस्ट्रीम' कॉल के बीच अधिकार खो देता है तो वास्तव में केवल (2) (अनुपयुक्त पहुंच विशेषाधिकार) के लिए दौड़ की स्थिति हो सकती है। यदि ऐसा होता है, तो 'अनधिकृत एक्सेस अपवाद' अपवाद फेंक दिया जाएगा, इसलिए आप अभी भी यह जान सकेंगे कि "पहुंच समस्या है"। इसके बाद आप ऊंचाई के कारण फेंकने वाले अपवाद को सुनिश्चित करने के लिए 'कैच (अनधिकृत एक्सेस अपवाद)' ब्लॉक के भीतर 'हैस्वाइटप्रमिशनऑनफ़ाइल' कॉल कर सकते हैं। – ken2k

+0

हा, ऐसा लगता है कि अनधिकृत एक्सेस अपवाद के लिए दौड़ की स्थिति को कैच ब्लॉक में ले जायेगा। हालांकि मुझे यकीन नहीं है कि इससे बचना संभव है। या वहाँ है? यह निश्चित रूप से सामान्य परिस्थितियों में काम करता है। धन्यवाद! – skybluecodeflier

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