2009-03-24 17 views
110

क्या क्लासलोडर के माध्यम से एक जार से पुनर्प्राप्त संसाधन पर फ़ाइल उदाहरण बनाने के लिए जावा में कोई तरीका है?फ़ाइल संसाधन के रूप में जावा संसाधन

मेरा एप्लिकेशन जार (डिफ़ॉल्ट) से कुछ फ़ाइलों या रनटाइम (उपयोगकर्ता इनपुट) पर निर्दिष्ट फाइल सिस्टम निर्देशिका से उपयोग करता है। जाहिर है, आदर्श दृष्टिकोण: मैं
क) लोड हो रहा है एक धारा
ख के रूप में इन फ़ाइलों) जार में उपयोगकर्ता परिभाषित निर्देशिका में फाइल या निर्देशिका लिस्टिंग क्रमशः

संपादित करने का संगत तरीका के लिए देख रहा हूँ पूरी तरह से java.io.File से दूर रहना होगा। क्या क्लासपाथ से निर्देशिका लोड करने का कोई तरीका है और इसकी सामग्री (इसमें निहित फाइलें/संस्थाएं) सूचीबद्ध हैं?

उत्तर

53

ClassLoader.getResourceAsStream और Class.getResourceAsStream निश्चित रूप से संसाधन डेटा लोड करने के लिए जाने का तरीका हैं। हालांकि, मुझे विश्वास नहीं है कि क्लासपाथ के तत्व की सामग्री "लिस्टिंग" का कोई तरीका है।

कुछ मामलों में यह बस असंभव हो सकता है - उदाहरण के लिए, एक ClassLoader मक्खी पर डेटा, क्या संसाधन नाम इसके लिए कहा है के आधार पर उत्पन्न कर सकता है। यदि आप ClassLoader एपीआई देखें (जो मूल रूप से क्लासपाथ तंत्र के माध्यम से काम करता है) तो आप देखेंगे कि आप जो चाहते हैं उसे करने के लिए कुछ भी नहीं है।

यदि आपको पता है कि आपको वास्तव में एक जार फ़ाइल मिली है, तो आप यह उपलब्ध कराने के लिए ZipInputStream के साथ लोड कर सकते हैं। इसका मतलब यह होगा कि आपके पास निर्देशिकाओं और जार फ़ाइलों के लिए अलग-अलग कोड होंगे।

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

+3

मैं सहमत हूं कि यह कष्टप्रद है - लेकिन यह क्लासलोडर को अन्य तरीकों से अधिक व्यापक रूप से लागू करता है। उदाहरण के लिए, "वेब क्लासलोडर" लिखना आसान है क्योंकि वेब फ़ाइलों को लाने के लिए अच्छा है, लेकिन यह आमतौर पर * सूची * फाइल नहीं है। –

+0

ऐसा लगता है कि जिस संसाधन को आप लोड करने का प्रयास कर रहे हैं वह 1 एमआईबी से बहुत बड़ा है, 'getResourceAsStream' से प्राप्त' इनपुटस्ट्रीम 'उस आकार के बाद संसाधन के बाइट्स को पुनर्प्राप्त करने के लिए बंद हो जाता है और इसके बजाय 0 अगर यह संपीड़ित फाइल सिस्टम में निहित होता है एक जार की तरह आपको लगता है कि 'getResource' का उपयोग करने के लिए मजबूर होना चाहिए और उस मामले में फ़ाइल को स्वतंत्र रूप से लोड करें। – mgttlinger

+0

@mgttlinger: यह मेरे लिए असंभव लगता है ... शायद यदि आप कर सकते हैं तो एक रेपो के साथ एक नया प्रश्न पोस्ट करने लायक है। –

5

इस प्रयास करें:

ClassLoader.getResourceAsStream ("some/pkg/resource.properties"); 

अधिक उपलब्ध तरीकों, उदा रहे हैं यहां देखें: http://www.javaworld.com/javaworld/javaqa/2003-08/01-qa-0808-property.html

+0

आपकी प्रतिक्रिया के लिए धन्यवाद। मैं getResourceAsStream के बारे में जानता हूं, लेकिन मुझे नहीं लगता कि मैं कक्षा के माध्यम से उस निर्देशिका से एक निर्देशिका लोड कर सकता हूं। – Mantrum

+0

जावा निर्देशिका में एक फ़ाइल है (यूनिक्स जड़ें मुझे लगता है) ताकि आपको कम से कम प्रयास करना चाहिए। – topchef

+0

मुझे लगता है कि एक निर्देशिका में फ़ाइलों को सूचीबद्ध करने के लिए आपको java.io.File का उपयोग करने की आवश्यकता होगी। आप क्लासलोडर के साथ फाइलें देख सकते हैं।findResource जो एक यूआरएल देता है जिसे फ़ाइल में पास किया जा सकता है। –

91

मैं एक ही समस्या थी और निम्न का उपयोग करने में सक्षम था:

// Load the directory as a resource 
URL dir_url = ClassLoader.getSystemResource(dir_path); 
// Turn the resource into a File object 
File dir = new File(dir_url.toURI()); 
// List the directory 
String files = dir.list() 
+37

यह दृष्टिकोण क्लासपाथ में JAR के साथ काम नहीं करता है, केवल फाइलों और निर्देशिकाओं के साथ – yegor256

+1

यही वही है जो मैं चाहता हूं! वास्तव में thx – StrikeW

+1

@ yegor256 यदि आपकी फ़ाइल एक जार में है तो आप 'फाइल सिस्टम' ऑब्जेक्ट बना सकते हैं और उस से 'पथ' प्राप्त कर सकते हैं। फिर आप इसे सामान्य की तरह पढ़ सकते हैं। (http://stackoverflow.com/a/22605905/1876344 देखें) – mgttlinger

2

यह एक विकल्प है: http://www.uofr.net/~greg/java/get-resource-listing.html

+2

जबकि यह लिंक प्रश्न का उत्तर दे सकता है, [यह बेहतर होगा] (// meta.stackoverflow.com/q/8259) के आवश्यक भागों को शामिल करने के लिए यहां जवाब दें, और संदर्भ के लिए लिंक प्रदान करें, क्योंकि एक लिंक बदल सकता है या लिंक किया गया पृष्ठ हटाया जा सकता है, जिससे जवाब बेकार हो जाता है। – JonasCz

48

यहाँ मेरी अनुप्रयोगों में से एक से कोड का एक सा है ... Let मुझे पता है कि यह आपकी जरूरतों के अनुरूप है या नहीं। यदि आप उस फ़ाइल को जानते हैं जिसका आप उपयोग करना चाहते हैं तो आप इसका उपयोग कर सकते हैं।

URL defaultImage = ClassA.class.getResource("/packageA/subPackage/image-name.png"); 
File imageFile = new File(defaultImage.toURI()); 

आशा है कि मदद करता है।

9

एक संसाधन एक जार से लिया गया पर एक फ़ाइल उदाहरण के निर्माण के लिए एक विश्वसनीय तरीका (अस्थायी फ़ाइल जब JVM बाहर निकल जाता है हटा दिया जाएगा) एक अस्थायी फ़ाइल में एक धारा के रूप में संसाधन की प्रतिलिपि करने के लिए यह है:

public static File getResourceAsFile(String resourcePath) { 
    try { 
     InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath); 
     if (in == null) { 
      return null; 
     } 

     File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp"); 
     tempFile.deleteOnExit(); 

     try (FileOutputStream out = new FileOutputStream(tempFile)) { 
      //copy stream 
      byte[] buffer = new byte[1024]; 
      int bytesRead; 
      while ((bytesRead = in.read(buffer)) != -1) { 
       out.write(buffer, 0, bytesRead); 
      } 
     } 
     return tempFile; 
    } catch (IOException e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 
संबंधित मुद्दे