【问题标题】:java.net.URI.relativize doesn't work with JAR URIsjava.net.URI.relativize 不适用于 JAR URI
【发布时间】:2012-10-24 09:11:52
【问题描述】:

我有两个 URI 对象。一个指向 JAR 文件中的文件夹,另一个指向同一个 JAR 文件中的文件。该文件位于第一个 URI 指定的目录的子文件夹中。我喜欢创建一个相对 URI,因此生成的 URI 只包含 JAR 中文件的相对路径。

  • 文件夹 URI

    jar:file:/C:/Users/inagy/.m2/repository/hu/inagy/my-config-artifact/2.0-SNAPSHOT/my-config-artifact-2.0-SNAPSHOT.jar!/conf/
    
  • 资源 URI

    jar:file:/C:/Users/inagy/.m2/repository/hu/inagy/my-config-artifact/2.0-SNAPSHOT/my-config-artifact-2.0-SNAPSHOT.jar!/conf/somesubpath/someconfig.xml
    
  • 在调用folderUri.relativize(resourceURI) 之后,我期望得到以下 URI:

    somesubpath/someconfig.xml
    

但是我得到了resourceURI,这意味着根据URI class's Javadoc,JDK代码发现这两个路径彼此不相关。

这是一个错误还是我做错了什么?

【问题讨论】:

    标签: java uri


    【解决方案1】:

    我也对此感到有点恼火。答案没有与 JAR 文件的语义有关——它与 jar: URI 的语法有关。要“相对化”,URI 必须是分层的而不是不透明的。您会从 java.net.URI 的 JavaDoc 中注意到:

    在最高级别,字符串形式的 URI 引用(以下简称“URI”)具有以下语法

    [scheme:]scheme-specific-part[#fragment]
    

    ...

    不透明 URI 是绝对 URI,其特定于方案的部分不以斜杠字符 ('/') 开头。不透明的 URI 不需要进一步解析。

    ...

    分层 URI 需要根据语法进一步解析

    [scheme:][//authority][path][?query][#fragment]
    

    jar:file:///home/me/foo.jar!/conf/ 这样的 JAR URI 被解析为:

    • 方案=jar
    • 方案特定部分 = file:///home/me/foo.jar!/conf/
    • 片段 =(无)

    因为方案特定部分不以“/”开头,所以不能将其视为分层 URI。 URI 类不专门处理 jar:(或任何)URI,因此它无法识别 file:// 部分是嵌套的 URI, 是分层的。

    由于jar: URI 是不透明的且不分层的,因此它们受制于为URI#relativize() 记录的行为:

    给定 URI 与该 URI 的相对化计算为 如下:

    1. 如果此 URI 或给定 URI 不透明,[...],则返回给定 URI。

    编辑:省略了关于不透明 URI 的关键部分。

    【讨论】:

    • URI.resolve() 也不理解 jar 方案/协议。但是 URL(URL) 会这样做。
    【解决方案2】:

    somesubpath/someconfig.xml 不是 URI;缺少协议(如file:)。事实上,只有带有 jar:file:/C:/Users/inagy/.m2/repository/hu/inagy/my-config-artifact/2.0-SNAPSHOT/my-config-artifact-2.0-SNAPSHOT.jar!somesubpath/someconfig.xml 的完整 URL 是可以想象的,但 jar 协议不会处理基本文档/目录,例如 /conf

    所以你只能使用绝对路径。 URI 代表唯一资源标识符的结果。

    没有带有相关文档 (.js) 的基础文档 (.html)。


    URI 用于检索数据。 如何为 jar 中的文件编写相对 URI?相对于哪里?由于“jar:”协议只在java代码中使用,没有“当前文件”的上下文。 所以没有实现相对 URI。

    【讨论】:

    • 我已经对文件系统 URI 使用了相同的代码(以 file: 开头),并且 relativize 返回了我期望的相对文件路径作为相对 URI。 URI 类中甚至还有一个 isAbsolute() 函数来检查这一点。
    • @JoopEggen 这几乎在每一点上都是错误的。 JAR 文件中的目录的 JAR URI 肯定是可能的:如果您的 JAR 中有这样的目录,getClass().getClassLoader().getResource("conf/") 将返回它们。无论如何,JAR 文件的语义是无关紧要的,因为 URI 类只关心语法。
    • somepath/somefile.xml 一个URI。这是一个相对等级的。至于您的“JAR 中没有基础文档”理论:JAR 文件中的 HTML 文件具有链接的相对 URI 呢?没有概念上的理由说明您不能拥有相对于 JAR URI 的 URI。这里的问题是语法。
    • @TimYates:阅读了您的回答 - 这让我很高兴,只是因为它的定义形式,我在回答中提出了jar:解释/理由,没有状态(基础文件)。我的回答是:正常的 jar 处理没有 current base。我想说一个java编程的网络浏览器主要可以相对化,你说不是因为缺少(=非法)jar://+/。你在技术上是正确的,你得到了我的支持。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    相关资源
    最近更新 更多