用于 URL 的 java.nio.file.Path?

Posted

技术标签:

【中文标题】用于 URL 的 java.nio.file.Path?【英文标题】:java.nio.file.Path for URLs? 【发布时间】:2012-02-05 16:46:15 【问题描述】:

Java7 为本地文件提供了默认的Path 实现。 是否有用于 URL 的路径实现?

例如,我应该能够使用以下代码复制远程资源:

Path remote = Paths.get(new URI("http://www.example.com/foo/bar.html"));
Path local = Paths.get(new URI("/bar.html"));
Files.copy(remote, local);

目前,这会抛出 java.nio.file.FileSystemNotFoundException: Provider "http" not installed。我可能可以自己实现这个,但我不想重新发明***。

【问题讨论】:

Files.copy(InputStream, Path) 有什么问题? URL 是否构成了通往网络世界的路径?还是它们更像指针?您可能会获得什么? @owlstead,我的图书馆需要向用户返回不透明的路径。他们可以将这些(只读)路径复制到本地文件系统,而无需知道或关心文件是驻留在本地(即数据库中)还是远程(Web 服务器)。 InputStreams 缺少我想为我的用户提供的属性,例如文件名或 lastModified 时间戳 明白了,但是用户看到的不一定要通过底层实现来体现。 @owlstead,我不明白。什么意思? 虽然用户可能将其视为路径,但您不一定必须使用新的 FileSystem 架构来实现它。目录列表之类的东西可能无论如何都没有启用。这并不是说你不能,但实施它可能不值得。 【参考方案1】:

看起来您真正想做的是完成 FTP 所做的事情 - 将文件从一个地方复制到另一个地方。我建议您使用现有的 FTP 代码库找到更好的方法。

URI 不是文件系统路径,因此您不能这样对待它们。它们是地址/资源定位器,当您使用浏览器(或处理它们的另一个客户端)到那里时,它们会触发它们背后的服务器定义的某些操作。该服务器的功能没有标准,因此 Web 服务具有灵活性。因此,如果您的服务器以这种方式接受 HTTP 请求以方便文件复制,您将不得不自己动手,并将文件数据传递到 POST 请求中。

换一种说法,(1) 不要将 URI 视为文件系统路径 - 它们不是,(2) 找到一个 FTP 库来复制文件,和/或 (3) 如果你真的想要要构建执行此操作的 Web 服务,请通过 POST 请求抽象文件复制的详细信息。如果您了解#3,您的建筑非常接近定制,并且它可能仅适用于遵循您的特定设计的部分网站(即您自己建造的网站)。没有标准的参数集或通过 POST 命令的“文件复制”,我知道您可以利用它来使这个“正常工作”——您必须将您的 HTTP 请求与 Web 服务相匹配服务器端。

【讨论】:

不管怎样,有人在issues.apache.org/jira/browse/VFS-199 推出了一个通用的HTTP 目录浏览器。就我而言,Web 服务器需要遵循我指定的目录结构,因此我需要推出相应的 Path 实现。感谢您帮助我了解为什么需要自定义实现。 Coolio - 很高兴我能帮上忙,也很高兴你找到了那个项目。 @normalocity 这几乎是不相关的,我只是想着想,但我认为目前 Java 7 中没有一种方法可以返回 Path classpath 资源,这将是非常好的。你怎么看?我认为这会很好,因为PathURL 好得多。 @KohányiRóbert,这实际上是一个绝妙的主意!我鼓励您构建它并将链接发送给我们。说真的。 嗯,我想是的。我通常在应用程序路径下使用我的所有资源编写应用程序,因此我可以始终依赖相对路径。但是,我知道很多人编写的应用程序会故意超出他们自己的本地目录,这可能对他们有用。【参考方案2】:

我不得不处理一个类似的问题并写了一个小方法来解决这个问题,你可以在下面找到。

它可以很好地连接 URL 和相关后缀。由于 URI 解析函数的行为,请注意不要给后缀绝对值。

private URI resolveURI(String root, String suffix) 
    URI uri;
    try 
        uri = new URI(root + "/").resolve(suffix);
     catch (URISyntaxException e) 
        //log
    
    return uri;

【讨论】:

【参考方案3】:

你可以这样做:

URI uri = new URI("http://www.example.com/foo/bar.html");
try (InputStream is = uri.toURL().openStream()) 
    // ...

它适用于 httphttpsfile 开箱即用,可能还有更多。

对于相对 URI,您必须先解析它们:

URI relative = new URI("bar.html");
URI base = new URI("http://www.example.com/foo/");
URI absolute = base.resolve(relative);
System.out.println(absolute); // prints "http://www.example.com/foo/bar.html"

现在您可以在absolute URI 上调用toURL().openStream()

【讨论】:

以上是关于用于 URL 的 java.nio.file.Path?的主要内容,如果未能解决你的问题,请参考以下文章

C++:url 阅读器功能不适用于带有 \ 符号的 URL 链接。请帮助我

Quickblox 不适用于子域 url

用于打开 URL 的 Shell 脚本

用于 url 检查的 ValidationProvider 规则

用于存储 URL 的数据类型

用于触摸 ID 和密码设置的 iOS 首选项 url 方案