2012-09-12 9 views
14

this question का उत्तर देने का प्रयास करने में, मुझे यह जानकर आश्चर्य हुआ कि उस फ़ाइल को पहले से मौजूद होने पर एक नई फ़ाइल बनाने का प्रयास करना एक अद्वितीय अपवाद प्रकार नहीं फेंकता है, यह सिर्फ फेंकता है एक सामान्य IOExceptionअपवाद कोड, या "फ़ाइल पहले से मौजूद है" का पता लगाने का प्रकार

इसलिए मैं यह सोचने के लिए छोड़ रहा हूं कि IOException किसी मौजूदा फ़ाइल का परिणाम है, या कुछ अन्य आईओ त्रुटि है।

अपवाद में एचआरएसल्ट है, लेकिन यह संपत्ति सुरक्षित है, और इस प्रकार मेरे लिए अनुपलब्ध है।

एकमात्र अन्य तरीका जो मैं देख सकता हूं वह पैटर्न स्ट्रिंग से मेल खाता है जो भयानक लगता है।

उदाहरण:

try 
{ 
    using (var stream = new FileStream("C:\\Test.txt", FileMode.CreateNew)) 
    using (var writer = new StreamWriter(stream)) 
    { 
     //write file 
    } 
} 
catch (IOException e) 
{ 
    //how do I know this is because a file exists? 
} 
+6

आप क्यों नहीं बस यदि फ़ाइल मौजूद है देखने के लिए जाँच नहीं है? चुम्मा। –

+3

क्योंकि एक फाइल सिस्टम स्वाभाविक रूप से अस्थिर है। फ़ाइलों को किसी भी समय बनाया जा सकता है (न केवल मेरे द्वारा)। – GazTheDestroyer

+1

कई त्रुटियों को एक अपवाद में लंपाने के साथ उन्हें अलग करने का कोई तरीका नहीं है, शायद .NET फ्रेमवर्क डिज़ाइन की सबसे खराब विशेषता है। आपके पास डिस्क पूर्ण, नेटवर्क पथ नहीं मिला, आदि IOExceptions के साथ एक ही समस्या है। यहां तक ​​कि यदि आप एचआरएसल्ट कोड प्राप्त करते हैं, तो यदि आपके कोड को लिनक्स पर मोनो के तहत भी चलाने की आवश्यकता है, तो यह – jimvfr

उत्तर

7
try 
{ 
    using (var stream = new FileStream("C:\\Test.txt", FileMode.CreateNew)) 
    using (var writer = new StreamWriter(stream)) 
    { 
     //write file 
    } 
} 
catch (IOException e) 
{ 
    var exists = File.Exists(@"C:\Text.text"); // =) 
} 

अस्थायी फ़ाइलों आदि जो फिर से हटा दिया गया है के लिए काम नहीं करेंगे।

+0

दुर, वास्तव में बहुत स्पष्ट, धन्यवाद! – GazTheDestroyer

+4

यह निर्धारिक तरीका नहीं है: अपवाद फेंकने के बाद फ़ाइल हटा दी जा सकती है लेकिन कैच ब्लॉक में चेक करने से पहले। – SerG

+1

यही कारण है कि मैंने कहा था कि 'अस्थायी फ़ाइलों आदि के लिए काम नहीं करेगा जो शायद हटा दिए गए हैं' – jgauffin

0

आप

FileMode.Create 

बजाय

की

FileMode.CreateNew 
का उपयोग करना चाहिए अगर इसके पहले से मौजूद है यह एक फ़ाइल पर आ जाएगी।

+2

मैं ओवरराइट नहीं करना चाहता अगर यह मौजूद है। – GazTheDestroyer

0

आप नहीं कर सकते। दुर्भाग्यवश IOExceptions को .NET ढांचे में मेरी समझ से परे किसी कारण से आगे निर्दिष्ट नहीं किया गया है।

लेकिन एक नई फ़ाइल बनाने के मामले में यह जांचना आम बात है कि फ़ाइल पहले मौजूद है या नहीं। इस तरह:

 try 
     { 
      if (File.Exists("C:\\Test.txt")) 
      { 
       //write file 

       using (var stream = new FileStream("C:\\Test.txt", FileMode.CreateNew)) 
       using (var writer = new StreamWriter(stream)) 
       { 
        //The actual writing of file 

       } 

      } 
     } 
     catch (IOException ex) 
     { 
      //how do I know this is because a file exists? 
      Debug.Print(ex.Message); 
     } 

शायद वह उत्तर नहीं जिसे आप ढूंढ रहे थे। लेकिन, सीएस्ट सीए

+0

समस्या यह है: एक और प्रक्रिया * * उस चेक के बीच फ़ाइल बना सकती है जो यह मौजूद है और इसे बनाने का प्रयास कर रही है। एक और समाधान यह जांचने के लिए हो सकता है कि फ़ाइल विफल * विफल होने के बाद * मौजूद है या नहीं। –

+0

सच है। अच्छा निर्णय। –

0

यह 100% सरल नहीं है (वहाँ एक IOException के लिए अन्य कारणों से कर रहे हैं), लेकिन आप कम से कम सभी व्युत्पन्न अपवाद प्रकारों को छोड़ कर सकते हैं:

try 
{ 
    ... 
} 
catch(IOException e) 
{ 
    if (e is UnauthorizedAccessException) throw; 
    if (e is DirectoryNotFoundException) throw; 
    if (e is PathTooLongException) throw; 
    // etc for other exceptions derived from IOException 

    ... assume file exists 
} 

या समकक्ष:

try 
{ 
    ... 
} 
catch(UnauthorizedAccessException) 
{ 
    throw; 
} 
catch(DirectoryNotFoundException) 
{ 
    throw; 
} 
catch(PathTooLongException) 
{ 
    throw; 
} 
catch(IOException e) 
{ 
    ... assume file exists 
} 

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

5

आप इस शर्त को IOException के लिए अपने कैच स्टेटमेंट में रख सकते हैं: if(ex.Message.Contains("already exists")) { ... }। यह एक हैक है, लेकिन यह सभी मामलों के लिए काम करेगा कि एक फ़ाइल मौजूद है, यहां तक ​​कि अस्थायी फ़ाइलें और ऐसे।

2

@jgauffin को संशोधित करने के सी # 6 में, आप when खंड के अंदर File.Exists का उपयोग catch ब्लॉक और इस तरह behaving more like an actual dedicated exception में प्रवेश से बचने के लिए कर सकते हैं:

try 
{ 
    using (var stream = new FileStream("C:\\Test.txt", FileMode.CreateNew)) 
    using (var writer = new StreamWriter(stream)) 
    { 
     //write file 
    } 
} 
catch (IOException e) when (File.Exists(@"C:\Text.text")) 
{ 
    //... 
} 
2

आप एक नया फ़ाइल बनाने के लिए प्रयास करते हैं और यह पहले से मौजूद है IOException Hresult = 0x80070050 (-2147024816) होगा।

तो तुम कोड ऐसा दिखाई दे सकता:

try 
{ 
    using (var stream = new FileStream("C:\\Test.txt", FileMode.CreateNew)) 
    using (var writer = new StreamWriter(stream)) 
    { 
     //write file 
    } 
} 
catch (IOException e) 
{ 
    if (e.HResult == -2147024816) 
    { 
     // File already exists. 
    } 
} 
+0

HResult को संरक्षित किया जाता था (मेरा तीसरा पैराग्राफ देखें) इसलिए यह केवल .Net4.5 में मान्य होना प्रतीत होता है, लेकिन यह जानकर उपयोगी है कि यह अब उपलब्ध है, धन्यवाद। – GazTheDestroyer

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