जावा में सापेक्ष पथ के साथ खुला संसाधन


84

मेरे जावा ऐप में मुझे कुछ फाइलें और निर्देशिकाएं प्राप्त करने की आवश्यकता है।

यह कार्यक्रम संरचना है:

./main.java
./package1/guiclass.java
./package1/resources/resourcesloader.java
./package1/resources/repository/modules/   -> this is the dir I need to get
./package1/resources/repository/SSL-Key/cert.jks    -> this is the file I need to get

guiclass संसाधन लोडर वर्ग को लोड करता है जो मेरे संसाधनों (निर्देशिका और फ़ाइल) को लोड करेगा।

फ़ाइल के रूप में, मैंने कोशिश की

resourcesloader.class.getClass().getResource("repository/SSL-Key/cert.jks").toString()

वास्तविक रास्ता पाने के लिए, लेकिन यह तरीका काम नहीं करता है।

मुझे पता नहीं है कि डायरेक्टरी के लिए कौन सा रास्ता इस्तेमाल करना है।


1
class.getClass () class.getClassLoader () के समान नहीं है। एक और उपाय भी है, getResourceAsStream () अपने संसाधन के समान पैकेज में एक वर्ग का उपयोग करना। अधिक जानकारी के लिए: tshikatshikaaa.blogspot.nl/2012/07/...
जेरोमे वर्स्ट्रीज

जवाबों:


48

क्लास लोडर के सापेक्ष पथ की आपूर्ति करें, उस वर्ग से नहीं जो आप लोडर से प्राप्त कर रहे हैं। उदाहरण के लिए:

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();

161

मुझे getClass().getResource("filename.txt")विधि का उपयोग करने में समस्या थी । जावा डॉक्स निर्देशों को पढ़ने पर, यदि आपका संसाधन उसी पैकेज में नहीं है जिस वर्ग से आप संसाधन तक पहुंचने की कोशिश कर रहे हैं, तो आपको इसे सापेक्ष पथ देना होगा '/'। अनुशंसित रणनीति को रूट निर्देशिका में "संसाधन" फ़ोल्डर के तहत अपनी संसाधन फ़ाइलों को रखना है। उदाहरण के लिए यदि आपके पास संरचना है:

src/main/com/mycompany/myapp

फिर आप मावेन द्वारा अनुशंसित संसाधन फ़ोल्डर जोड़ सकते हैं:

src/main/resources

इसके अलावा आप संसाधन फ़ोल्डर में सबफ़ोल्डर जोड़ सकते हैं

src/main/resources/textfiles

और कहते हैं कि आपकी फ़ाइल को myfile.txtआपके पास बुलाया जाता है

src/main/resources/textfiles/myfile.txt

अब यहां वह जगह है जहां बेवकूफ पथ की समस्या आती है। कहो कि आपके पास एक वर्ग है com.mycompany.myapp package, और आप myfile.txtअपने संसाधन फ़ोल्डर से फ़ाइल तक पहुंचना चाहते हैं । कुछ लोग कहते हैं:

"/main/resources/textfiles/myfile.txt" path

या

"/resources/textfiles/myfile.txt"

ये दोनों गलत हैं। मेरे दौड़ने के बाद mvn clean compile, फ़ाइलों और फ़ोल्डरों में कॉपी किया जाता है:

myapp/target/classes 

फ़ोल्डर। लेकिन रिसोर्स फोल्डर नहीं है, सिर्फ रिसोर्स फोल्डर में फोल्डर हैं। मतलब आपके पास है:

myapp/target/classes/textfiles/myfile.txt

myapp/target/classes/com/mycompany/myapp/*

इसलिए getClass().getResource("")विधि को देने का सही मार्ग है:

"/textfiles/myfile.txt"

यह रहा:

getClass().getResource("/textfiles/myfile.txt")

यह अब शून्य नहीं लौटेगा, बल्कि आपकी कक्षा को लौटा देगा। मुझे उम्मीद है कि इससे किसी को मदद मिलेगी। यह मेरे लिए अजीब है, कि "resources"फ़ोल्डर को कॉपी नहीं किया गया है, लेकिन केवल सबफ़ोल्डर्स और सीधे "resources"फ़ोल्डर में फ़ाइलें । यह मेरे लिए तर्कसंगत होगा कि "resources"फ़ोल्डर भी नीचे पाया जाएगा"myapp/target/classes"


1
मेरे में target/classes, मैं केवल मुख्य संसाधनों के तहत फाइलें देख सकता हूं और संसाधनों का परीक्षण नहीं कर सकता। क्यों?
अवा

@Ava अपने स्रोत फ़ोल्डर के रूप में परीक्षण फ़ोल्डर जोड़ें और आप जाने के लिए अच्छे हैं!
आकाश पाराशर

@Ava, यकीन है कि यह आपके लिए देर से जवाब है, लेकिन किसी की मदद कर सकते हैं। आप पर अमल करने की जरूरत है mvn clean test-compileके रूप में यह करने के बाद चला जाता है, आदेश compileमें Maven जीवन चक्र । वह उत्पन्न करेगा target/test-classes
अलेक्जेंडर रेडचेंको

34

उन लोगों के लिए अतिरिक्त जानकारी प्रदान करने की उम्मीद में जो इसे दूसरों की तरह जल्दी नहीं उठाते हैं, मैं अपना परिदृश्य प्रदान करना चाहता हूं क्योंकि इसकी थोड़ी अलग स्थापना है। मेरा प्रोजेक्ट निम्न निर्देशिका संरचना (ग्रहण का उपयोग करके) के साथ सेटअप किया गया था:

परियोजना /
  src / // एप्लीकेशन सोर्स कोड
    org /
      मेरी परियोजना/
        MyClass.java
  परीक्षण / // इकाई परीक्षण
  रेस / // संसाधन
    आइकन के लिए छवियों / // PNG छवियों
      मेरी-image.png
    JAXB के साथ XML फ़ाइलों को मान्य करने के लिए xml / // XSD फाइलें
      मेरी-schema.xsd
    Log4j के लिए conf / // default .conf फ़ाइल
      log4j.conf
  lib / // लाइब्रेरीज़ को प्रोजेक्ट सेटिंग्स के माध्यम से बिल्ड-पाथ में जोड़ा जाता है

मुझे रेस निर्देशिका से अपने संसाधन लोड करने में समस्या हो रही थी । मैं अपने सभी संसाधनों को अपने स्रोत कोड (बस प्रबंधन / संगठन उद्देश्यों के लिए) से अलग करना चाहता था। इसलिए, मुझे जो करना था, वह रेज- डायरेक्टरी को बिल्ड-पाथ में जोड़ दिया गया और फिर रिसोर्स को एक्सेस किया:

static final ClassLoader loader = MyClass.class.getClassLoader();

// in some function
loader.getResource("images/my-image.png");
loader.getResource("xml/my-schema.xsd");
loader.getResource("conf/log4j.conf");

नोट:/ संसाधन स्ट्रिंग की शुरुआत से छोड़ दिया जाता है, क्योंकि मैं उपयोग कर रहा हूँ ClassLoader.getResource (स्ट्रिंग) के बजाय Class.getResource (स्ट्रिंग)


1
क्लासलैडर सुझाने के लिए + 1
pyb

1
इस विषय पर सर्वश्रेष्ठ उत्तर! /संसाधन पथ की शुरुआत में उपयोग नहीं करने के बारे में टिप महत्वपूर्ण थी!
Kayhadrin

10

जब आप क्लास में 'getResource' का उपयोग करते हैं, तो क्लास के अंदर पैकेज के आधार पर एक सापेक्ष पथ हल हो जाता है। जब आप ClassLoader पर 'getResource' का उपयोग करते हैं, तो रूट फ़ोल्डर के आधार पर एक सापेक्ष पथ को हल किया जाता है।

यदि आप एक निरपेक्ष पथ का उपयोग करते हैं, तो दोनों 'getResource' विधियाँ रूट फ़ोल्डर में शुरू होंगी।


के प्रभावों को मत भूलना/
गिल्बर्टो

@nbeyer getResourceरूट फ़ोल्डर में निरपेक्ष पथ के साथ प्रयोग क्यों शुरू होता है? क्या निरपेक्ष मार्ग का उद्देश्य पूर्ण नहीं है ?
एटजुआ

10

@GianCarlo: आप सिस्टम प्रॉपर्टी user.dir को कॉल करने का प्रयास कर सकते हैं जो आपको अपने जावा प्रोजेक्ट की जड़ देगा और फिर इस पथ को उदाहरण के लिए अपने रिश्तेदार पथ पर जोड़ देगा:

String root = System.getProperty("user.dir");
String filepath = "/path/to/yourfile.txt"; // in case of Windows: "\\path \\to\\yourfile.txt
String abspath = root+filepath;



// using above path read your file into byte []
File file = new File(abspath);
FileInputStream fis = new FileInputStream(file);
byte []filebytes = new byte[(int)file.length()];
fis.read(filebytes);

1
ओपी क्लासपाथ में एक संसाधन का पता लगाना चाहता था (वें बिल्ड के दौरान उत्पन्न जार में सबसे अधिक संभावना है)। यह विधि उस लक्ष्य को प्राप्त करने का एक तरीका प्रदान नहीं करती है - आप Fileजार फ़ाइल के अंदर एक संसाधन को इंगित नहीं कर सकते हैं , केवल फ़ाइल सिस्टम में एक उचित प्रविष्टि (जैसे जार स्वयं)।
अत्तिला

मुझे वांछित मार्ग को देखने के लिए "user.dir" प्राप्त करने का विचार पसंद है। धन्यवाद
YouAreAwesome 10

5

ग्रहण + मावेन का उपयोग करने वालों के लिए। आप फ़ाइल images/pic.jpgमें प्रवेश करने का प्रयास करें src/main/resources। इस तरह से करना:

ClassLoader loader = MyClass.class.getClassLoader();
File file = new File(loader.getResource("images/pic.jpg").getFile());

पूरी तरह से सही है, लेकिन इसके परिणामस्वरूप एक शून्य सूचक अपवाद हो सकता है। ग्रहण की तरह लगता है कि मावेन डायरेक्टरी स्ट्रक्चर में फोल्डर को फोल्डर को सोर्स फोल्डर के रूप में तुरंत पहचानता नहीं है। src/main/resourcesप्रोजेक्ट के स्रोत फ़ोल्डर सूची से फ़ोल्डर को हटाकर और इसे वापस रखकर (प्रोजेक्ट> गुण> जावा बिल्ड पथ> स्रोत> निकालें / फ़ोल्डर जोड़ें), मैं इसे हल करने में सक्षम था।


2
resourcesloader.class.getClass()

को तोड़ा जा सकता है:

Class<resourcesloader> clazz = resourceloader.class;
Class<Class> classClass = clazz.getClass();

इसका मतलब है कि आप बूटस्ट्रैप क्लास का उपयोग करके संसाधन को लोड करने का प्रयास कर रहे हैं।

इसके बजाय आप शायद ऐसा कुछ चाहते हैं:

resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()

यदि केवल javac ने गैर-स्थिर संदर्भों पर स्थिर तरीकों को कॉल करने के बारे में चेतावनी दी ...


1

निम्नलिखित कार्य करें?

resourcesloader.class.getClass().getResource("/package1/resources/repository/SSL-Key/cert.jks")

क्या कोई कारण है कि आप पैकेज सहित पूर्ण पथ निर्दिष्ट नहीं कर सकते हैं?


1

ऊपर वर्णित दो उत्तरों के साथ जा रहे हैं। पहले वाला

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()

एक और एक ही बात होनी चाहिए?


1

फ़ाइल के लिए वास्तविक पथ प्राप्त करने के लिए आप यह कोशिश कर सकते हैं:

URL fileUrl = Resourceloader.class.getResource("resources/repository/SSL-Key/cert.jks");
String pathToClass = fileUrl.getPath;    

Resourceloader यहाँ classname है। "रिसोर्स / रिपॉजिटरी / एसएसएल-की / सर्टिफिकेट.जेक्स" फाइल के सापेक्ष पथ है। यदि आपके पास फ़ोल्डर संरचना के बाकी हिस्सों के साथ ./package1/java में आपके मार्गदर्शक थे, तो आप "../resources/repository/SSL-Key/cert.jks" को संबंधित पथ के कारण नियमों के सापेक्ष पथ के रूप में ले लेंगे।

इस तरह से आप अपनी फाइल को बफर्डरीडर के साथ पढ़ सकते हैं। फ़ाइल का पथ पहचानने के लिए STRING का उपयोग न करें, क्योंकि यदि आपके पथ में अंग्रेज़ी वर्णमाला के रिक्त स्थान या कुछ वर्ण नहीं हैं, तो आपको समस्याएँ आएंगी और फ़ाइल नहीं मिलेगी।

BufferedReader bufferedReader = new BufferedReader(
                        new InputStreamReader(fileUrl.openStream()));

0

मैंने .getFile()null पॉइंटर अपवाद से बचने और डेटा निर्देशिका के लिए पथ सेट करने के लिए @ jonathan.cone के एक लाइनर (जोड़कर ) पर एक छोटा संशोधन किया । यहाँ मेरे लिए क्या काम किया गया है:

String realmID = new java.util.Scanner(new java.io.File(RandomDataGenerator.class.getClassLoader().getResource("data/aa-qa-id.csv").getFile().toString())).next();

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.