2012-06-13 16 views
96

मेरे पास मेरे प्रोजेक्ट की रूट में संसाधन फ़ोल्डर/पैकेज है, मैं "निश्चित नहीं" एक निश्चित फ़ाइल लोड करना चाहता हूं। अगर मैं एक निश्चित फाइल लोड करना चाहता था, तो मैं class.getResourceAsStream का उपयोग करूंगा और मैं ठीक हूँ !! मैं वास्तव में क्या करना चाहता हूं संसाधन फ़ोल्डर के भीतर "फ़ोल्डर" लोड करना, उस फ़ोल्डर के अंदर फ़ाइलों पर लूप करना और प्रत्येक फ़ाइल में स्ट्रीम प्राप्त करना और सामग्री में पढ़ना ... मान लें कि फ़ाइल नाम रनटाइम से पहले निर्धारित नहीं हैं ... मुझे क्या करना चाहिए? क्या आपके जार फ़ाइल में फ़ोल्डर के अंदर फ़ाइलों की सूची प्राप्त करने का कोई तरीका है? सूचना है कि संसाधनों के साथ जार फ़ाइल में एक ही जार फ़ाइल जहाँ से कोड रन किया जा रहा है ...मैं अपने जार फ़ाइल के अंदर से "फ़ोल्डर" संसाधन कैसे प्राप्त कर सकता हूं?

अग्रिम धन्यवाद ...

+1

इससे मदद मिलेगी: http://stackoverflow.com/questions/1529611/how-to-write-a-java-program-which-can-extract-a-jar-file-and-store-its-data -इन-एस –

+0

यह भी देखें: http://stackoverflow.com/questions/4764347/extract-and-load-dll-from-jar –

+4

पहला वाला एक जार फ़ाइल निकालने के बारे में है, जो कि आखिरी चीज है कोशिश करना चाहते हैं, एक बदतर-बदतर स्थिति की तरह !! अगर मैं निकाली गई फाइलों को चाहता हूं, तो मैं उन्हें इंस्टॉलेशन समय पर अपने इंस्टॉलेशन फ़ोल्डर में डाल दूंगा! मैं उन्हें जार के अंदर से एक्सेस करना चाहता हूं, और मेरा कारण यह है कि, अगर रिसोर्सएस्ट्रीम एक फ़ाइल तक पहुंच सकता है, जावा भी उस जार में फ़ोल्डरों को एक्सप्लोर करने की आवश्यकता के बिना एक्सप्लोर करने में सक्षम होना चाहिए !! लेकिन धन्यवाद ... –

उत्तर

86

अंत में, मैं

final String path = "sample/folder"; 
final File jarFile = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath()); 

if(jarFile.isFile()) { // Run with JAR file 
    final JarFile jar = new JarFile(jarFile); 
    final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar 
    while(entries.hasMoreElements()) { 
     final String name = entries.nextElement().getName(); 
     if (name.startsWith(path + "/")) { //filter according to the path 
      System.out.println(name); 
     } 
    } 
    jar.close(); 
} else { // Run with IDE 
    final URL url = Launcher.class.getResource("/" + path); 
    if (url != null) { 
     try { 
      final File apps = new File(url.toURI()); 
      for (File app : apps.listFiles()) { 
       System.out.println(app); 
      } 
     } catch (URISyntaxException ex) { 
      // never happens 
     } 
    } 
} 

दूसरे खंड बस जब आप आईडीई (जार फ़ाइल के साथ नहीं) पर एप्लिकेशन को चलाने के काम करते हैं, आप इसे हटा सकते हैं अगर आप ऐसा नहीं करते हैं: समाधान मिल गया।

+0

सही उत्तर अपडेट किया गया।यद्यपि यह ऐसा नहीं है जो मैं करना चाहता हूं, खासकर 34000+ स्रोत फ़ाइलों वाले कोड में ... लेकिन ऐसा लगता है कि यह एकमात्र समाधान है। धन्यवाद। –

+2

FYI, यह वेबस्टार्ट से लॉन्च होने पर काम नहीं करता है क्योंकि GetPath सर्वर के डोमेन से संबंधित कुछ देता है। – amos

+0

यह सोचें कि यह पथ काम करने जा रहा है यदि पथ एक जार में है, तो यह त्रुटि टूरू रूपांतरण पर देगी: java.lang.IllegalArgumentException: यूआरआई पदानुक्रमित नहीं है – tribbloid

-18

यह link आप कैसे बताता है।

InputStream is = 
this.getClass().getClassLoader().getResourceAsStream("yourpackage/mypackage/myfile.xml") 
+13

कोई दोस्त नहीं !! मुझे एक फाइल नहीं चाहिए !! मुझे एक पूरा फ़ोल्डर चाहिए, जिनकी उप फाइलें अनिश्चित प्री-रनटाइम हैं !!! –

15

निम्नलिखित का प्रयास करें:

जादू getResourceAsStream() विधि है।
संसाधन पथ बनाएं "<PathRelativeToThisClassFile>/<ResourceDirectory>" E.g. यदि आपका वर्ग पथ com.abc.package.MyClass है और अपने Resoure फ़ाइलों के भीतर कर रहे हैं src/com/एबीसी/पैकेज/संसाधन /:

URL url = MyClass.class.getResource("resources/"); 
if (url == null) { 
    // error - missing folder 
} else { 
    File dir = new File(url.toURI()); 
    for (File nextFile : dir.listFiles()) { 
     // Do something with nextFile 
    } 
} 

तुम भी उपयोग कर सकते हैं

URL url = MyClass.class.getResource("/com/abc/package/resources/"); 
+16

समय और प्रयास के लिए धन्यवाद, लेकिन यह तब काम नहीं करता जब आपका कोड बेस .jar फ़ाइल में और आपके संसाधनों में भी है .jar फ़ाइल। जब आप एक .jar फ़ाइल के अंदर होते हैं, तो आप एक फ़ाइल() नहीं बना सकते हैं और आपको उस फ़ोल्डर के लिए यूआरएल भी नहीं मिल सकता है ... मैं व्यक्तिगत रूप से इसके साथ शांति में आया और बस प्रत्येक फ़ाइल को एक्सएमएल में सूचीबद्ध किया ... मैं नहीं ' टी लगता है कि आप एक जार फ़ाइल के अंदर एक फ़ोल्डर के लिए ऐसा कर सकते हैं ... –

+2

क्षमा करें कि आपकी समस्याएं हैं। हालांकि, यह वास्तव में काम करता है जब आपका कोड बेस जार फ़ाइल में होता है और आपके संसाधन उस जार फ़ाइल में भी होते हैं। आप डिस्क पर फ़ाइल() नहीं बना रहे हैं - आप जावा मेमोरी में जार फ़ाइल के भीतर फ़ाइल पढ़ रहे हैं। ध्यान दें कि क्लासलोडर डिस्क पर एक निर्देशिका के बराबर एक जार फ़ाइल का इलाज करने के लिए काफी खुश है। स्रोत से विवरण यहां दिया गया है: –

+0

थ्रेड.current थ्रेड()। GetContextClassLoader()। GetResource ("Hello.txt"); –

1

सरल ... ओएसजीआई का उपयोग करें। ओएसजीआई में आप अपने बंडल की प्रविष्टियों को findEntries और findPaths के साथ पुन: सक्रिय कर सकते हैं।

+0

दरअसल, यह एक बहुत अच्छा विचार की तरह लगता है, धन्यवाद ... –

+6

यदि इसमें ओएसजीआई शामिल है तो मैं शायद इसे 'सरल' कहूंगा। लेकिन अगर आप पहले से ही ओएसजीआई का उपयोग कर रहे हैं ... हाँ यकीन है। लेकिन इस विशेष समस्या को हल करने के लिए ओएसजीआई में जाने का सुझाव थोड़ा सा लगता है। – Kris

+0

ओएसजीआई कई अन्य समस्याओं को हल करता है और आजकल इसे शुरू करना बहुत आसान है। ओएसजीआई एन रूट ट्यूटोरियल देखें –

0

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

URL inputUrl = getClass().getResource("/upload/blabla1.txt"); 
File dest1 = new File("upload/blabla1.txt"); 
FileUtils.copyURLToFile(inputUrl, dest1); 

URL inputUrl2 = getClass().getResource("/upload/blabla2.txt"); 
File dest2 = new File("upload/blabla2.txt"); 
FileUtils.copyURLToFile(inputUrl2, dest2); 

URL inputUrl3 = getClass().getResource("/upload/blabla3.txt"); 
File dest3 = new File("upload/Bblabla3.txt"); 
FileUtils.copyURLToFile(inputUrl3, dest3); 
+1

हाय, उत्तर के लिए धन्यवाद, लेकिन, आप देखते हैं, कोड लिखते समय आपको उस फ़ोल्डर के अंदर प्रत्येक फ़ाइल का नाम जानना होगा; और आपको प्रत्येक को स्पष्ट रूप से नाम देना था। जो मैं खोज रहा था वह फ़ोल्डर के अंदर फ़ाइलों पर पुन: प्रयास करने और रनटाइम पर अपने नाम प्राप्त करने का एक तरीका था, इसलिए मैं कोड को बदलने के बिना फ़ोल्डर में संसाधन जोड़ सकता था, यह जानकर कि कोड उन्हें भी संसाधित करेगा। हालांकि आपके समय के लिए धन्यवाद। : 3 –

5

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

+0

एक आकर्षण की तरह काम करता है! – Blanka

+0

यह तब तक अच्छी तरह से काम करता है जब तक कि आप चीजों को झुकाव की योजना बनाते हैं, जैसा कि यह निकलता है। – Tustin2121

4

मुझे हाथों में एक ही समस्या थी, जबकि मैं जार में पैक किए गए संसाधनों से कुछ हडूप कॉन्फ़िगरेशन लोड करने का प्रयास कर रहा था ... आईडीई और जार (रिलीज संस्करण) दोनों पर।

मुझे स्थानीय फाइल सिस्टम और जार दोनों पर निर्देशिका सामग्री पर पुनरावृत्त करने के लिए सर्वोत्तम काम करने के लिए java.nio.file.DirectoryStream मिला।

String fooFolder = "/foo/folder"; 
.... 

ClassLoader classLoader = foofClass.class.getClassLoader(); 
try { 
    uri = classLoader.getResource(fooFolder).toURI(); 
} catch (URISyntaxException e) { 
    throw new FooException(e.getMessage()); 
} catch (NullPointerException e){ 
    throw new FooException(e.getMessage()); 
} 

if(uri == null){ 
    throw new FooException("something is wrong directory or files missing"); 
} 

/** i want to know if i am inside the jar or working on the IDE*/ 
if(uri.getScheme().contains("jar")){ 
    /** jar case */ 
    try{ 
     URL jar = FooClass.class.getProtectionDomain().getCodeSource().getLocation(); 
     //jar.toString() begins with file: 
     //i want to trim it out... 
     Path jarFile = Paths.get(jar.toString().substring("file:".length())); 
     FileSystem fs = FileSystems.newFileSystem(jarFile, null); 
     DirectoryStream<Path> directoryStream = Files.newDirectoryStream(fs.getPath(fooFolder)); 
     for(Path p: directoryStream){ 
      InputStream is = FooClass.class.getResourceAsStream(p.toString()) ; 
     performFooOverInputStream(is); 
     /** your logic here **/ 
      } 
    }catch(IOException e) { 
     throw new FooException(e.getMessage());  
    } 
} 
else{ 
    /** IDE case */ 
    Path path = Paths.get(uri); 
    try { 
     DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path); 
     for(Path p : directoryStream){ 
      InputStream is = new FileInputStream(p.toFile()); 
      performFooOverInputStream(is); 
     } 
    } catch (IOException _e) { 
     throw new FooException(_e.getMessage()); 
    } 
} 
0

एक अन्य समाधान है, आप इसे ResourceLoader इस तरह उपयोग कर सकते हैं:

import org.springframework.core.io.Resource; 
import org.apache.commons.io.FileUtils; 

@Autowire 
private ResourceLoader resourceLoader; 

... 

Resource resource = resourceLoader.getResource("classpath:/path/to/you/dir"); 
File file = resource.getFile(); 
Iterator<File> fi = FileUtils.iterateFiles(file, null, true); 
while(fi.hasNext()) { 
    load(fi.next()) 
} 
1

निम्नलिखित कोड पथ के रूप में करना चाहता था "फ़ोल्डर" रिटर्न अगर यह एक जार या नहीं अंदर है की परवाह किए बिना।

private Path getFolderPath() throws URISyntaxException, IOException { 
    URI uri = getClass().getClassLoader().getResource("folder").toURI(); 
    if ("jar".equals(uri.getScheme())) { 
     FileSystem fileSystem = FileSystems.newFileSystem(uri, Collections.emptyMap(), null); 
     return fileSystem.getPath("path/to/folder/inside/jar"); 
    } else { 
     return Paths.get(uri); 
    } 
    } 

जावा 7+ की आवश्यकता है।

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

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