正如vbezhenear所說的那樣,以及我自己的實驗,c:/testfs/my-outer.jar!/my-inner.jar
形式的JarURLConnection符號似乎沒有通過工廠方法FileSystems.newFileSystem(Path path, ClassLoader loader)
實施。
但你仍然可以訪問內瓶這樣的:如果您嘗試使用URI
而不是Path
,你可以創建一個ZipFileSystem
這樣
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
方法的內部jar中直接創建文件系統。
從查找到ZipFileSystem的反編譯源代碼,它似乎只支持「真實」文件。對於嵌套的ZIP(jar)壓縮包,你需要使用「低級別」java.util.zip包(或者將內部的arcive提取到磁盤上,儘管我不會說這是一個好的解決方案)。 – vbezhenar
不是一個好主意。即使是一個級別的JAR文件系統也會表現很差。 – EJP