2010-04-09 9 views
26

मैं कोड लिख रहा हूं जो इस OutOfMemoryException को पकड़ता है और एक नया, अधिक सहज ज्ञान युक्त अपवाद फेंकता है:क्या कोई कारण है Image.FromFile एक अवैध छवि प्रारूप के लिए OutOfMemoryException फेंकता है?

/// ... 
/// <exception cref="FormatException">The file does not have a valid image format.</exception> 
public static Image OpenImage(string filename) 
{ 
    try 
    { 
     return Image.FromFile(filename); 
    } 
    catch(OutOfMemoryException ex) 
    { 
     throw new FormatException("The file does not have a valid image format.", ex); 
    } 
} 

क्या यह कोड अपने उपयोगकर्ता को स्वीकार्य है, या OutOfMemoryException जानबूझकर किसी विशेष कारण के लिए फेंक दिया जा रहा है?

उत्तर

36

नहीं, यह इतिहास है। जीडीआई + कुछ समय पहले लिखा गया था .NET कभी भी आया था। इसके लिए एसडीके रैपर सी ++ में लिखा गया था। अपवाद सी ++ में iffy हैं, हर कोई इन में खरीद नहीं है। Google उदाहरण के लिए नहीं है। तो इसे संगत रखने के लिए यह त्रुटि कोड के साथ समस्याओं की रिपोर्ट करता है।यह कभी भी अच्छी तरह से स्केल नहीं करता है, लाइब्रेरी प्रोग्रामर इसे जानबूझकर संभावित त्रुटि कोडों की संख्या को सीमित करने का लक्ष्य बनाते हैं, इससे क्लाइंट प्रोग्रामर पर बोझ कम हो जाता है।

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

स्थिति :: आउटऑफमेमरी त्रुटि कोड अलग-अलग चीज़ों के लिए ओवरलोड हो गया है। कभी-कभी यह वास्तव में स्मृति से बाहर होता है, यह बिटमैप बिट्स को स्टोर करने के लिए पर्याप्त स्थान आवंटित नहीं कर सकता है। अफसोस की बात है, एक छवि फ़ाइल प्रारूप समस्या एक ही त्रुटि कोड द्वारा रिपोर्ट किया जाता है। यहां घर्षण यह है कि यह संभवतः यह तय नहीं कर सकता कि छवि फ़ाइल से चौड़ाई * ऊंचाई * पिक्सल पढ़ी गई है या नहीं, क्योंकि बिटमैप के लिए पर्याप्त संग्रहण उपलब्ध नहीं है। या यदि छवि फ़ाइल में डेटा जंक है। यह मानता है कि छवि फ़ाइल जंक नहीं है, उचित कॉल, यह एक और प्रोग्राम की समस्या है। तो ओओएम यह रिपोर्ट करता है।

enum Status 
{ 
    Ok = 0, 
    GenericError = 1, 
    InvalidParameter = 2, 
    OutOfMemory = 3, 
    ObjectBusy = 4, 
    InsufficientBuffer = 5, 
    NotImplemented = 6, 
    Win32Error = 7, 
    WrongState = 8, 
    Aborted = 9, 
    FileNotFound = 10, 
    ValueOverflow = 11, 
    AccessDenied = 12, 
    UnknownImageFormat = 13, 
    FontFamilyNotFound = 14, 
    FontStyleNotFound = 15, 
    NotTrueTypeFont = 16, 
    UnsupportedGdiplusVersion = 17, 
    GdiplusNotInitialized = 18, 
    PropertyNotFound = 19, 
    PropertyNotSupported = 20, 
#if (GDIPVER >= 0x0110) 
    ProfileNotFound = 21, 
#endif //(GDIPVER >= 0x0110) 
}; 
+3

इनमें से लगभग * इनमें से कोई भी 'आउटऑफमेमरी' से भी बेहतर विकल्प होगा, यहां तक ​​कि 'जेनेरिक एरर' भी। – MusiGenesis

+11

विशेष रूप से 'अज्ञात इमेजफॉर्मैट' एक प्रारूप के लिए उपयुक्त लगता है जिसे समझा नहीं जा सकता है। –

7

अच्छा, यह एक अच्छा उदाहरण है कि अपवाद का हमेशा यह अर्थ नहीं होता कि यह क्या कहता है। This particular case (OutOfMemoryException किसी अमान्य फ़ाइल के लिए) .NET 1.0 पर वापस आता है, जिसमें अपवाद प्रकारों का अधिक सीमित सेट था, जिससे इस लाइब्रेरी के प्रोग्रामर चुन सकते थे। मुझे लगता है कि तब से यह पीछे की संगतता को बनाए रखने के लिए नहीं बदला गया है (ए.के.ए. "खराब होने के बाद अच्छा पैसा फेंकना)"।

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

3

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

2

यह एक भ्रामक अपवाद है। माइक्रोसॉफ्ट says:

जब आप .NET फ्रेमवर्क में Bitmap.FromFile विधि का उपयोग करने 1.0

यह समस्या तब हो सकती है जब आप का उपयोग करने की कोशिश एक "System.OutOfMemoryException" त्रुटि संदेश प्राप्त Bitmap.FromFile विधि और निम्न स्थितियों में से एक सत्य है:

  • छवि फ़ाइल दूषित हो गई है।
  • छवि फ़ाइल अपूर्ण है।

नोट यदि आपके आवेदन एक फ़ाइल धारा है कि एक फ़ाइल के लिए लिख पूरा नहीं हुआ है पर Bitmap.FromFile विधि का उपयोग करने की कोशिश कर रहा है इस समस्या का अनुभव कर सकते हैं। * छवि फ़ाइल में वैध छवि प्रारूप नहीं है या GDI + फ़ाइल के पिक्सेल प्रारूप का समर्थन नहीं करता है। * कार्यक्रम में छवि फ़ाइल तक पहुंचने की अनुमति नहीं है। * पृष्ठभूमि छवि संपत्ति बिटमैप से सीधे सेट की गई है। FromFile विधि।

(बिटमैप छवि से उतरता है)

बेशक

, यह भी इस अपवाद प्राप्त करना संभव है जब आप एक छवि है जो बहुत बड़ा है लोड करने के लिए प्रयास करें। तो आपको उस पर विचार करने की जरूरत है।

+0

यह लगभग तब भी जब यह गूगल पर पहली हिट है लिंक जोड़ने के लायक नहीं है:

पूर्णता के लिए, इन त्रुटि कोड है। :) – MusiGenesis

+2

@MusiGenesis: कोई तर्क दे सकता है कि सवाल का जवाब देने योग्य नहीं है। :) (तो मैंने क्यों किया? मुझे नहीं पता) –

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