fileName
आप कैसे गुजर रहे हैं, इसकी व्याख्या करने के लिए सूक्ष्म अंतर हैं। मूल रूप से, आपके पास 2 अलग-अलग विधियाँ हैं: ClassLoader.getResourceAsStream()
और Class.getResourceAsStream()
। ये दो विधियाँ संसाधन को अलग-अलग तरीके से ढूँढेगी।
में Class.getResourceAsStream(path)
, पथ को उस पथ के स्थानीय पथ के रूप में व्याख्या किया जाता है जिस वर्ग से आप इसे कॉल कर रहे हैं। उदाहरण के फोन करने के लिए, String.getResourceAsStream("myfile.txt")
निम्न स्थान पर अपने classpath में एक फ़ाइल के लिए दिखेगा: "java/lang/myfile.txt"
। यदि आपका मार्ग ए से शुरू होता है /
, तो इसे एक पूर्ण मार्ग माना जाएगा, और क्लासपाथ की जड़ से खोजना शुरू कर देगा। इसलिए कॉलिंग String.getResourceAsStream("/myfile.txt")
आपके क्लास पथ में निम्न स्थान पर दिखेगा ./myfile.txt
।
ClassLoader.getResourceAsStream(path)
सभी रास्तों को निरपेक्ष पथ मानेंगे। इसलिए कॉलिंग String.getClassLoader().getResourceAsStream("myfile.txt")
और String.getClassLoader().getResourceAsStream("/myfile.txt")
निम्नलिखित स्थान पर दोनों आपके वर्गपथ में एक फ़ाइल की तलाश करेंगे:./myfile.txt
।
हर बार जब मैं इस पोस्ट में किसी स्थान का उल्लेख करता हूं, तो यह आपके फाइलसिस्टम में ही एक स्थान हो सकता है, या संबंधित जार फ़ाइल के अंदर, आपके द्वारा संसाधन लोड किए जाने वाले वर्ग और / या क्लासऑलडर पर निर्भर करता है।
आपके मामले में, आप अनुप्रयोग सर्वर से कक्षा को लोड कर रहे हैं, इसलिए आपको Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)
इसके बजाय का उपयोग करना चाहिए this.getClass().getClassLoader().getResourceAsStream(fileName)
।this.getClass().getResourceAsStream()
काम भी करेगा।
उस विशेष समस्या के बारे में अधिक विस्तृत जानकारी के लिए इस लेख को पढ़ें ।
टॉमकैट 7 और उससे नीचे के उपयोगकर्ताओं के लिए चेतावनी
इस सवाल के जवाब में से एक में कहा गया है कि मेरा स्पष्टीकरण टॉमकैट 7 के लिए गलत लगता है। मैंने यह देखने के लिए चारों ओर देखने की कोशिश की है कि ऐसा क्यों होगा।
इसलिए मैंने टॉमकैट के WebAppClassLoader
कई संस्करणों के लिए टॉमकैट के स्रोत कोड को देखा है । findResource(String name)
(जो अनुरोधित संसाधन के लिए URL का उत्पादन करने के लिए अत्यंत उत्तरदायी है) का कार्यान्वयन वस्तुतः Tomcat 6 और Tomcat 7 में समान है, लेकिन Tomcat 8 में भिन्न है।
संस्करण 6 और 7 में, कार्यान्वयन संसाधन नाम को सामान्य करने का प्रयास नहीं करता है। इसका मतलब यह है कि इन संस्करणों में, घटना के classLoader.getResourceAsStream("/resource.txt")
रूप में उसी परिणाम का उत्पादन नहीं हो सकता है , classLoader.getResourceAsStream("resource.txt")
हालांकि यह होना चाहिए (जब से कि Javadoc निर्दिष्ट करता है)। [सोर्स कोड]
संस्करण 8 में हालांकि, संसाधन नाम की गारंटी सामान्यीकृत है कि संसाधन नाम का पूर्ण संस्करण वह है जिसका उपयोग किया जाता है। इसलिए, टॉमकैट 8 में, ऊपर वर्णित दो कॉल हमेशा एक ही परिणाम वापस करना चाहिए। [सोर्स कोड]
नतीजतन, आपको 8. से पहले ClassLoader.getResourceAsStream()
या Class.getResourceAsStream()
टॉमकैट संस्करणों का उपयोग करते समय अतिरिक्त सावधानी बरतनी होगी और आपको यह भी ध्यान रखना होगा कि class.getResourceAsStream("/resource.txt")
वास्तव में कॉल classLoader.getResourceAsStream("resource.txt")
(अग्रणी /
छीन लिया गया है)।
getClass().getResourceAsStream("/myfile.txt")
अलग व्यवहार होता हैgetClassLoader().getResourceAsStream("/myfile.txt")
।