如何为另一个罐子内的罐子创建一个文件系统



我正在尝试使用NIO文件系统访问另一个罐子内的罐子。把外面的罐子叫做我的外在.jar把内在的罐子叫做我的内在.jar(使用Java 8和Windows 7,但我认为这不是问题)

我正在使用以下代码

    String zipfilePath = "c:/testfs/my-outer.jar!/my-inner.jar";
    Path path = Paths.get(zipfilePath);
    try(ZipFileSystem zipfs = (ZipFileSystem) FileSystems.newFileSystem(path, null))
    { ...  }

但是在尝试创建该新文件系统时,我遇到了以下异常:

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

请注意,如果我只使用外部jar作为文件系统,则可以很好地工作,并且可以很好地从中读取和写入文件。只是当我试图进入内部档案时,麻烦就开始了。

文件系统不支持 JarURLConnection 表示法吗?

正如 vbezhenear 所说,正如我自己所实验的那样,c:/testfs/my-outer.jar!/my-inner.jar形式的 JarURLConnection 表示法似乎没有通过工厂方法实现FileSystems.newFileSystem(Path path, ClassLoader loader) .

但是您仍然可以像这样访问内部罐子:

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)) {
       ...
    }
}

--更新--

如果您尝试使用URI而不是Path则可以创建如下ZipFileSystem

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 上创建文件系统。

一个迟到的答案,但问题的标题是如何制作一个包含在另一个罐子中的 jar 的文件系统。 我对这个问题的解决方案是将包含的 jar 解压缩到临时位置,然后使用该提取的 jar 位置创建一个文件系统。如果您对提取的副本进行了任何更改,则必须将它们放回它来自的罐子中。当我不得不从 aar 文件中提取"类.jar"并将该罐子中的内容复制到另一个罐子时,我遇到了这个问题。就我而言,提取的副本永远不会被修改,因此简化了事情。

相关内容

最新更新