मैं जावा में संसाधन लोड करने का सबसे अच्छा तरीका जानना चाहता हूं:
this.getClass().getResource() (or getResourceAsStream())
,Thread.currentThread().getContextClassLoader().getResource(name)
,System.class.getResource(name)
।
मैं जावा में संसाधन लोड करने का सबसे अच्छा तरीका जानना चाहता हूं:
this.getClass().getResource() (or getResourceAsStream())
,Thread.currentThread().getContextClassLoader().getResource(name)
,System.class.getResource(name)
।जवाबों:
आप जो चाहते हैं उसी के अनुसार समाधान निकालें ...
वहाँ दो चीजें हैं जो कर रहे हैं getResource
/ getResourceAsStream()
वर्ग इस पर कहा जाता है से मिलेगा ...
इसलिए यदि आप
this.getClass().getResource("foo.txt");
यह foo.txt को "इस" वर्ग के समान पैकेज से और "इस" वर्ग के क्लास लोडर के साथ लोड करने का प्रयास करेगा। यदि आप सामने "/" डालते हैं तो आप संसाधन का संदर्भ दे रहे हैं।
this.getClass().getResource("/x/y/z/foo.txt")
"लोड" और xyz पैकेज के वर्ग लोडर से संसाधन को लोड करेगा (इसे उस पैकेज में कक्षाओं के समान निर्देशिका में होना होगा)।
Thread.currentThread().getContextClassLoader().getResource(name)
संदर्भ वर्ग लोडर के साथ लोड होगा, लेकिन किसी भी पैकेज के अनुसार नाम का समाधान नहीं करेगा (यह बिल्कुल संदर्भित होना चाहिए)
System.class.getResource(name)
सिस्टम क्लास लोडर के साथ संसाधन को लोड करेगा (इसे पूरी तरह से संदर्भित करना होगा, क्योंकि आप java.lang पैकेज (सिस्टम के पैकेज) में कुछ भी नहीं डाल पाएंगे।
बस स्रोत पर एक नज़र रखना। यह भी इंगित करता है कि getResourceAsStream केवल URL पर "openStream" कॉल करता है जो getResource से लौटा है और जो लौटाता है।
Thread#setContextClassLoader
। यह उपयोगी है यदि आपको प्रोग्राम निष्पादित करते समय क्लासपाथ को संशोधित करने की आवश्यकता है।
ठीक है, यह आंशिक रूप से निर्भर करता है कि आप क्या करना चाहते हैं यदि आप वास्तव में एक व्युत्पन्न वर्ग में हैं।
उदाहरण के लिए, मान लें कि SuperClass
एज़ेर में है और SubClass
B.jar में है, और आप एक इंस्टेंस विधि में कोड निष्पादित कर रहे हैं, SuperClass
लेकिन जहां this
एक इंस्टेंस को संदर्भित करता है SubClass
। यदि आप इसका उपयोग this.getClass().getResource()
करते हैं SubClass
, तो B.jar में इसके सापेक्ष दिखेगा । मुझे संदेह है कि आमतौर पर है वह नहीं है जिसकी आवश्यकता है।
व्यक्तिगत रूप से मैं शायद Foo.class.getResourceAsStream(name)
सबसे अधिक बार उपयोग करूंगा - यदि आप पहले से ही उस संसाधन का नाम जानते हैं जो आप के बाद का है, और आप निश्चित हैं कि यह कहां के सापेक्ष है Foo
, तो यह आईएमओ करने का सबसे मजबूत तरीका है।
बेशक कई बार जब वह नहीं आप क्या चाहते हैं, भी: अपनी योग्यता के आधार पर प्रत्येक मामले न्यायाधीश। यह सिर्फ "मुझे पता है कि यह संसाधन इस वर्ग से जुड़ा हुआ है" सबसे आम है जिसे मैंने चलाया है।
this.getClass()
। उपवर्ग का एक उदाहरण बनाएं और विधि को कॉल करें ... यह उपवर्ग का नाम प्रिंट करेगा, न कि सुपरक्लास।
मैं तीन स्थानों की खोज करता हूं जैसा कि नीचे दिखाया गया है। टिप्पणियाँ स्वागत है।
public URL getResource(String resource){
URL url ;
//Try with the Thread Context Loader.
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if(classLoader != null){
url = classLoader.getResource(resource);
if(url != null){
return url;
}
}
//Let's now try with the classloader that loaded this class.
classLoader = Loader.class.getClassLoader();
if(classLoader != null){
url = classLoader.getResource(resource);
if(url != null){
return url;
}
}
//Last ditch attempt. Get the resource from the classpath.
return ClassLoader.getSystemResource(resource);
}
मुझे पता है कि यह वास्तव में एक और जवाब के लिए देर हो चुकी है, लेकिन मैं सिर्फ वही साझा करना चाहता था जिसने आखिर में मेरी मदद की। यह फ़ाइल सिस्टम के पूर्ण पथ (न केवल क्लासपैथ के) से संसाधनों / फ़ाइलों को लोड करेगा।
public class ResourceLoader {
public static URL getResource(String resource) {
final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
classLoaders.add(Thread.currentThread().getContextClassLoader());
classLoaders.add(ResourceLoader.class.getClassLoader());
for (ClassLoader classLoader : classLoaders) {
final URL url = getResourceWith(classLoader, resource);
if (url != null) {
return url;
}
}
final URL systemResource = ClassLoader.getSystemResource(resource);
if (systemResource != null) {
return systemResource;
} else {
try {
return new File(resource).toURI().toURL();
} catch (MalformedURLException e) {
return null;
}
}
}
private static URL getResourceWith(ClassLoader classLoader, String resource) {
if (classLoader != null) {
return classLoader.getResource(resource);
}
return null;
}
}
मैंने बहुत सारे तरीके और फ़ंक्शन आज़माए, जो ऊपर दिए गए थे, लेकिन उन्होंने मेरे प्रोजेक्ट में काम नहीं किया। वैसे भी मुझे समाधान मिल गया है और यहाँ यह है:
try {
InputStream path = this.getClass().getClassLoader().getResourceAsStream("img/left-hand.png");
img = ImageIO.read(path);
} catch (IOException e) {
e.printStackTrace();
}
this.getClass().getResourceAsStream()
इस मामले में बेहतर उपयोग करना चाहिए । यदि आप getResourceAsStream
विधि के स्रोत पर एक नज़र डालते हैं , तो आप देखेंगे कि यह आपकी तुलना में एक ही काम करता है लेकिन एक बेहतर तरीके से (यदि ClassLoader
कक्षा में कोई भी नहीं पाया जा सकता है)। यह भी पता चलता है कि आप एक संभावित सामना कर सकते हैं null
पर getClassLoader
अपने कोड में ...
this.getClass().getResourceAsStream()
मेरे लिए काम नहीं कर रहा है, इसलिए मैं उस काम का उपयोग करता हूं। मुझे लगता है कि कुछ लोग हैं जो मेरी जैसी समस्या का सामना कर सकते हैं।