2015-04-17 11 views
6

मैं एक जार के अंदर एक जार का उपयोग करने की NIO FileSystem उपयोग करने के लिए कोशिश कर रहा हूँ अंदर एक जार करने के लिए एक फाइल सिस्टम बना सकते हैं। बाहर जार मेरी-outer.jar और भीतरी कॉल मेरी-inner.jar (जावा 8 और विंडोज 7 का उपयोग करते हुए, लेकिन मुझे लगता है कि मुद्दा नहीं है)कैसे मैं एक जार

मैं निम्नलिखित कोड

String zipfilePath = "c:/testfs/my-outer.jar!/my-inner.jar"; 
    Path path = Paths.get(zipfilePath); 
    try(ZipFileSystem zipfs = (ZipFileSystem) FileSystems.newFileSystem(path, null)) 
    { ... } 
उपयोग कर रहा हूँ

लेकिन मैं नीचे जब कि newFileSystem बनाते समय अपवाद हो रही है:

Exception in thread "main" java.nio.file.FileSystemNotFoundException: C:\testfs\my-outer.jar!\my-inner.jar 

ध्यान दें कि अगर मैं सिर्फ FileSystem के रूप में बाहरी जार, कि पूरी तरह से ठीक काम करता है का उपयोग करें और मैं इसे से खूबसूरती से पढ़ सकते हैं और फ़ाइलें लिख सकते हैं । यह तब होता है जब मैं आंतरिक संग्रह में पहुंचने की कोशिश करता हूं कि परेशानियां शुरू होती हैं।

JarURLConnection अंकन का समर्थन फाइल सिस्टम नहीं है?

+1

ZipFileSystem के स्रोतों decompiled को ऐसा लगता है कि यह केवल "असली" फ़ाइलों का समर्थन करता देख से। नेस्टेड ज़िप (जार) अभिलेखागार के लिए आपको "निम्न-स्तर" java.util.zip पैकेज (या डिस्क पर आंतरिक आर्केव निकालने की आवश्यकता होगी, हालांकि मैं इसे एक अच्छा समाधान नहीं कहूंगा)। – vbezhenar

+0

कोई अच्छा विचार नहीं है। यहां तक ​​कि एक-स्तर की जेएआर फाइल सिस्टम भी बहुत खराब प्रदर्शन करने जा रहा है। – EJP

उत्तर

3

जैसा कि vbezhenear ने कहा और स्वयं द्वारा प्रयोग किया गया है c:/testfs/my-outer.jar!/my-inner.jar रूप में JarURLConnection नोटेशन कारखाने विधि FileSystems.newFileSystem(Path path, ClassLoader loader) द्वारा लागू नहीं किया गया है।

लेकिन आप अभी भी इस तरह भीतरी जार पहुंच सकता है: क्या आप इस

की तरह एक ZipFileSystem बना सकते हैं एक Path के बजाय एक URI का उपयोग करने का प्रयास करें

Path outerPath = Paths.get("c:/testfs/my-outer.jar"); 
try (FileSystem outerFS = FileSystems.newFileSystem(outerPath, null)) { 
    Path innerPath = outerFS.getPath("/my-inner.jar"); 
    try (FileSystem innerFS = FileSystems.newFileSystem(innerPath, null)) { 
     ... 
    } 
} 

--UPDATE--

URI uri = URI.create("jar:file:/home/orto/stackoverflow/outer.jar!/inner.jar"); 
Map<String,String> env = Collections.emptyMap(); 
try(ZipFileSystem zipfs = (ZipFileSystem)FileSystems.newFileSystem(uri,env)) 
{...} 

लेकिन कोई भाग्य आपको outer.jar तक पहुंच प्राप्त नहीं करता है और inner.jar नहीं

आप JarFileSystemProvider के स्रोत कोड को देखो, तो आप देख

@Override 
protected Path uriToPath(URI uri) { 
    String scheme = uri.getScheme(); 
    if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) { 
     throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'"); 
    } 
    try { 
     String uristr = uri.toString(); 
     int end = uristr.indexOf("!/"); 
     uristr = uristr.substring(4, (end == -1) ? uristr.length() : end); 
     uri = new URI(uristr); 
     return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null)) 
        .toAbsolutePath(); 
    } catch (URISyntaxException e) { 
     throw new AssertionError(e); //never thrown 
    } 
} 

पथ पहले "!" से पहले काटा जाता है। तो वहाँ सीधे newFileSystem विधि से अंदर जार पर एक फाइल सिस्टम बनाने के लिए कोई रास्ता नहीं है।

+0

मुझे आपका पहला जवाब पसंद है। मुझे समझ में नहीं आया कि आपका "अपडेट" एक और जवाब दे रहा था या सिर्फ मेरे प्रश्न को समझा रहा है –

+2

"अपडेट" यह दिखाने के लिए है कि अभी भी उस सुविधा का कोई कार्यान्वयन नहीं है जिसे आप ढूंढ रहे थे। (JarURLConnection नोटेशन के साथ स्थित एक ZipFileSystem बनाना) –

+0

यह (अब 8u74 पर नहीं) 'फाइलसिस्टम। न्यूफाइल सिस्टम (आंतरिक पाथ, शून्य)' के रूप में काम करता है 'प्रदाता NotFoundException'' क्योंकि 'ZipFileSystemProvider.newFileSystem()' पथ से बाहर निकलता है .getFileSystem()! = FileSystems.getDefault() '। – antak

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