【问题标题】:Converting a Jar-URI into a nio.Path将 Jar-URI 转换为 nio.Path
【发布时间】:2015-12-28 16:48:13
【问题描述】:

在一般情况下,我无法从 URI 转换为 nio.Path。给定一个具有多个架构的 URI,我希望创建一个 nio.Path 实例来反映这个 URI。

    //setup
    String jarEmbeddedFilePathString = "jar:file:/C:/Program%20Files%20(x86)/OurSoftware/OurJar_x86_1.0.68.220.jar!/com/our_company/javaFXViewCode.fxml";
    URI uri = URI.create(jarEmbeddedFilePathString);

    //act
    Path nioPath = Paths.get(uri);

    //assert --any of these are acceptable
    assertThat(nioPath).isEqualTo("C:/Program Files (x86)/OurSoftware/OurJar_x86_1.0.68.220.jar/com/our_company/javaFXViewCode.fxml");
    //--or assertThat(nioPath).isEqualTo("/com/our_company/javaFXViewCode.fxml");
    //--or assertThat(nioPath).isEqualTo("OurJar_x86_1.0.68.220.jar!/com/our_company/javaFXViewCode.fxml")
    //or pretty well any other interpretation of jar'd-uri-to-path any reasonable person would have.

此代码当前在 Paths.get() 调用中抛出 FileSystemNotFoundException

这种转换的实际原因是询问结果路径关于它的包位置和文件名的事情——也就是说,只要结果路径对象保留了...com/our_company/javaFXViewCode.fxml部分,那么它仍然很方便供我们使用 NIO Path 对象。

大部分信息实际上是用于调试的,因此我可以改进我们的代码以避免在这个特定实例中使用路径,而是使用 URI 或简单的字符串,但这将涉及大量的重新工具对于 nio.Path 对象已经方便地提供的方法。

我已经开始深入研究the file system provider API 并且遇到了比我希望处理这么小的事情更复杂的问题。在 URI 指向非 jar 文件的情况下,是否有一种简单的方法可以从类加载器提供的 URI 转换为与操作系统可理解的遍历相对应的路径对象,并且不是操作系统可理解但仍然有用在路径指向 jar 内的资源(或就此而言是 zip 或 tarball)的情况下进行遍历?

感谢您的帮助

【问题讨论】:

    标签: java url path uri classloader


    【解决方案1】:

    Java Path 属于 FileSystem。文件系统由FileSystemProvider 实现。

    Java 带有两种文件系统提供程序:一种用于操作系统(例如WindowsFileSystemProvider),另一种用于 zip 文件(ZipFileSystemProvider)。这些是内部的,不应直接访问。

    要将Path 获取到Jar 文件中的文件,您需要获取(创建)FileSystem 以获取Jar 文件的内容。然后,您可以为该文件系统中的文件获取Path

    首先,您需要解析 Jar URL,最好使用 JarURLConnection

    URL jarEntryURL = new URL("jar:file:/C:/Program%20Files%20(x86)/OurSoftware/OurJar_x86_1.0.68.220.jar!/com/our_company/javaFXViewCode.fxml");
    JarURLConnection jarEntryConn = (JarURLConnection) jarEntryURL.openConnection();
    URL jarFileURL = jarEntryConn.getJarFileURL(); // file:/C:/Program%20Files%20(x86)/OurSoftware/OurJar_x86_1.0.68.220.jar
    String entryName = jarEntryConn.getEntryName(); // com/our_company/javaFXViewCode.fxml
    

    一旦你有了这些,你就可以创建一个FileSystem 并获得一个Path 到jar'd 文件。请记住,FileSystem 是开放资源,使用完后需要关闭:

    try (FileSystem jarFileSystem = FileSystems.newFileSystem(jarPath, null)) {
        Path entryPath = jarFileSystem.getPath(entryName);
        System.out.println("entryPath: " + entryPath); // com/our_company/javaFXViewCode.fxml
        System.out.println("parent: " + entryPath.getParent()); // com/our_company
    }
    

    【讨论】:

    • ++ 表示“文件系统需要关闭”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多