16

我正在运行的系统是带有 JRE 1.6 的 Windows XP。

我这样做:

public static void main(String[] args) {
    try {
        System.out.println(new File("C:\\test a.xml").toURI().toURL());
    } catch (Exception e) {
        e.printStackTrace();
    }       
}

我明白了:file:/C:/test%20a.xml

为什么给定的 URL 在 ? 之前没有两个斜杠C:?我预计file://C:...。这是正常行为吗?


编辑 :

来自 Java 源代码:java.net.URLStreamHandler.toExternalForm(URL)

    result.append(":");
    if (u.getAuthority() != null && u.getAuthority().length() > 0) {
        result.append("//");
        result.append(u.getAuthority());
    }

文件 URL 的权限部分似乎为空或为空,因此跳过了双斜杠。那么 URL 的权限部分是什么,文件协议中真的没有它吗?

4

3 回答 3

12

这是一个有趣的问题。

首先要做的事情是:我在 JRE6 上得到了相同的结果。当我去掉 toURL() 部分时,我什至明白了这一点。

RFC2396实际上并不需要两个斜杠。根据第 3 节:

URI 语法取决于方案。一般来说,绝对URI的写法如下:

<scheme>:<scheme-specific-part>

话虽如此,RFC2396 已被RFC3986取代,其中指出

通用 URI 语法由称为方案、权限、路径、查询和片段的组件的分层序列组成。

  URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]

  hier-part   = "//" authority path-abempty
              / path-absolute
              / path-rootless
              / path-empty

方案和路径组件是必需的,但路径可能为空(无字符)。存在权限时,路径必须为空或以斜杠 ("/") 字符开头。当权限不存在时,路径不能以两个斜杠字符(“//”)开头。这些限制导致路径有五个不同的 ABNF 规则(第 3.3 节),其中只有一个会匹配任何给定的 URI 引用。

所以,你去吧。由于文件 URI 没有权限段,因此禁止它们以 // 开头。

但是,该 RFC 直到 2005 年才出现,Java 引用 RFC2396,所以我不知道为什么它遵循这个约定,因为新 RFC 之前的文件 URL 总是有两个斜杠。

于 2009-07-15T13:40:03.500 回答
2

要回答为什么你可以同时拥有:

file:/path/file
file:///path/file
file://localhost/path/file

RFC3986(3.2.2. 主机)指出:

“如果 URI 方案为主机定义了默认值,那么当主机子组件未定义或注册名称为空(零长度)时,该默认值适用。例如,“文件”URI 方案被定义为没有权限,空主机和“localhost”都表示最终用户的机器,而“http”方案认为缺少权限或空主机无效。”

因此,“文件”方案转换file:///path/file为具有最终用户机器的上下文,即使权限是空主机。

于 2012-01-21T21:55:59.293 回答
1

就在浏览器中使用它而言,没关系。我通常见过file:///...,但一个、两个或三个“/”都可以。这让我认为(不查看 java 文档)这将是正常行为。

于 2009-07-15T13:28:27.410 回答