Java 中的资源、URI、URL、路径和文件有什么区别?

What's the difference between a Resource, URI, URL, Path and File in Java?

我现在正在查看一段 Java 代码,它将路径作为字符串并使用 URL resource = ClassLoader.getSystemClassLoader().getResource(pathAsString); 获取其 URL,然后调用 String path = resource.getPath() 最后执行 new File(path);

哦,还有对URL url = resource.toURI();String file = resource.getFile()的调用。

我现在完全糊涂了 - 我想主要是因为术语。有人可以带我了解一下差异,或者提供一些指向 Dummy-proof material 的链接吗?尤其是 URL 的 URI 和 文件 的资源?对我来说,感觉它们应该分别是同一个东西...

getFile()getPath()的区别这里解释一下:What's the difference between url.getFile() and getpath()?(有意思它们似乎都是 return 字符串,这可能使我的心态增加了很多...)

现在,如果我有一个引用 jar 文件中的 class 或包的定位器,这两个(即文件字符串的路径)是否会不同?

毕竟

resource.toString() 会给你 jar:file:/C:/path/to/my.jar!/com/example/(注意感叹号)。

URIURL在Java[=50中的区别=] 前者不编码空格?比照。 Files, URIs, and URLs conflicting in Java (This answer explains the general, conceptual difference between the two terms fairly well: URIs identify and URLs locate;)

最后 - 也是最重要的 - 为什么我需要 File 对象;为什么 Resource (URL) 不够?(还有 Resource 对象吗?)

抱歉,如果这个问题有点杂乱无章;它只是反映了我的困惑... :)

更新 2017-04-12 检查 因为它包含更详尽和准确的解释!


请注意,我不认为自己 100% 有能力回答,但是这里有一些评论:

  • File 表示可通过文件系统访问的文件或目录
  • resource 是可由应用程序加载的数据对象的 generic term
    • 通常资源是与应用程序/库一起分发并通过class-加载机制加载的文件(当它们位于class-路径时)
  • URL#getPath 在 URL (protocol://host/path?query)
  • 的路径部分是 getter
  • URL#getFile 根据 Java 文档 returns path+query

在Java中,URI只是一个操作通用标识符本身的数据结构。

另一方面,

URL 实际上是一个资源定位器,它为您提供了通过注册的 URLStreamHandler 实际读取资源的功能。

URLs 可以导致文件系统资源,您可以使用 file:// 协议为每个文件系统资源构造 URL(因此 File <-> URL关系)。

另请注意,URL#getFilejava.io.File 无关。


Why do I need File object; why isn't a Resource (URL) enough?

够了。只有当你想将资源传递给某个只能处理文件的组件时,你才需要从中获取 File 。但是,并非所有资源 URL 都可以转换为 File

And is there a Resource object?

从 JRE 的角度来看,它只是一个术语。一些框架为你提供了这样的class(例如Spring's Resource)。

据我了解,您可以将它们归类为:

基于 Web:URI 和 URLs。

  • URLs:URL 是互联网上的一个明确位置(只是一个普通的网址,如 - whosebug.com)
  • URI:曾经 URL 是一个 URI。但是 URI 也可以包含 "mailto:" 之类的东西,所以它们也是,嗯,我想说的是 "script"。

和本地:资源、路径和文件

  • 资源:资源是 jar 中的文件。它们用于从罐子/容器中加载文件。
  • 路径:路径基本上是一个字符串。但是它带有一些方便的函数来连接多个字符串,或者将文件添加到一个字符串中。它确保您正在构建的路径有效。
  • 文件:这是对目录或文件的引用。用于修改文件、打开文件等

如果将它们合并为一个会更容易 class - 它们真的很混乱 :D

希望对您有所帮助:)

(我刚刚看了文档 - 看看 docs.oracle.com)

文件是本地文件系统中实体的抽象表示。

路径通常是一个字符串,指示文件在文件系统中的位置。它通常不包括文件名。所以 c:\documents\mystuff\stuff.txt 的路径值为 "C:\documents\mystuff" 显然,绝对文件名和路径的格式因文件系统而异。

URL 是 URI 的子集,URL 通常表示可通过 http 访问的资源。我不认为有任何关于什么时候必须是 URI 与 URL 的铁律。 URI 是 "protocol://resource-identifier" 形式的字符串,例如 bitcoin://params, http://something.com?param=value。 Class像 URL 这样的通常会包装字符串并提供 String 没有理由提供的实用方法。

没有 Resource 之类的东西,至少在您所说的意义上没有。仅仅因为一个方法被命名为 getResource 并不意味着它 returns 一个 Resource 类型的对象。

最终弄清楚 Class 的方法做什么的最佳方法是在您的代码中创建它的一个实例,调用这些方法,然后在调试模式下单步执行或将结果发送到System.out。

不错。

正如他所说,"file" 这个词在 URL#getFilejava.io.File 中具有完全不同(几乎不相关)的含义 - 这可能是混淆的一部分。

补充一下:

  • Java中的一个resource是一个抽象的概念,是可以阅读的数据源。资源的位置(或地址)在 Java 中由 URL 对象表示。

  • 一个资源可以对应本地文件系统中的一个普通文件(具体来说,当它的URLfile://开头时) .但是资源更通用(它也可以是存储在 jar 中的一些文件,或者是一些要从网络读取的数据,或者从内存中,或者......)。而且它也更受限制,因为还可以创建和写入 File(除了常规文件以外的其他东西:目录,link)。

  • 记住在 Java 中一个 File 对象并不真正代表 "a file" 但位置(全名,带有文件的路径)。因此,File 对象允许您定位(和打开)文件,因为 URL 允许您访问(和打开)资源。 (Java中没有Resource class代表资源,也没有代表文件!再说一遍:File不是文件,是文件路径)。

I'm totally confused right now - mostly because of the terminology, I guess. Can someone please walk me through the differences, or provide a few links to Dummy-proof material? Especially URI to URL and Resource to File? To me, it feels like they should be the same thing, respectively...

术语令人困惑,有时令人困惑,并且主要源于 Java 作为 API 和平台随着时间的推移而演变。要理解这些术语是如何产生含义的,重要的是要认识到影响 Java 设计的两件事:

  • 向后兼容性。旧应用程序应该运行在较新的安装上,理想情况下无需修改。这意味着需要在所有新版本中维护旧的 API(及其名称和术语)。
  • 跨平台。 API 应该提供其底层平台的可用抽象,无论是操作系统还是浏览器。

我将详细介绍这些概念以及它们是如何形成的。之后我会回答你的其他具体问题,因为我可能不得不参考第一部分的内容。

什么是“资源”?

可以定位和读取的抽象的通用数据。 笼统地说,Java 用它来指代可能不存在的“文件”一个文件,但确实代表了一段命名的数据。 它在Java中没有直接的class或接口表示,但由于其属性(可定位、可读),它通常由[=155表示=].

因为 Java 的早期设计目标之一是 运行 在浏览器中,作为沙盒应用程序(小程序!),rights/privileges/security 权限非常有限,Java 明确(理论上)文件(本地文件系统上的东西)和资源(需要读取的东西)之间的区别。 这就是为什么读取与应用程序(图标、class 文件等)是通过 ClassLoader.getResource 而不是通过文件 class.

完成的

不幸的是,因为“资源”也是一个有用的通用术语在这种解释之外,它也被用来命名非常具体的事物(例如class ResourceBundle, UIResource, Resource) 从这个意义上说,它们不是资源。

表示资源(路径)的主要 class 是 java.nio.file.Path, java.io.File, java.net.URI, and java.net.URL

File (java.io, 1.0)

An abstract representation of file and directory pathnames.

文件 class 表示可通过平台的本机文件系统访问的资源。它只包含文件名,所以它实际上更像是宿主平台根据自己的设置、规则和语法解释的路径(见后文)。

请注意,File 不需要指向某些东西 local,只需指向主机平台在文件访问上下文中理解的东西,例如Windows 中的 UNC 路径。如果您在 OS 中将 ZIP 文件作为文件系统装载,则 File 将很好地读取其包含的条目。

URL (java.net, 1.0)

Class URL represents a Uniform Resource Locator, a pointer to a "resource" on the World Wide Web. A resource can be something as simple as a file or a directory, or it can be a reference to a more complicated object, such as a query to a database or to a search engine.

与资源的概念相结合,URL 表示该资源的方式与文件 class 表示主机平台中的文件的方式相同:作为 结构化字符串指向一个资源。 URL 还包含一个提示如何访问资源的方案(“文件:”是“询问主机平台”),因此允许通过以下方式指向资源HTTP、FTP、在 JAR 中等等。

不幸的是,URL有自己的语法和术语,包括“文件”和“路径”的使用。如果 URL 是一个文件 - URL,URL.getFile 将 return 一个与引用文件的路径字符串相同的字符串。

Class.getResource returns an URL: 比returning File更灵活,满足了早期想象中的系统需求1990年代

URI (java.net, 1.4)

Represents a Uniform Resource Identifier (URI) reference.

URI 是对 URL. URI 和 URL 的(轻微)抽象在正式意义上,涵盖更广泛的用例。因为 URL 和 URI are/were 不是一回事,引入了一个新的 class 来表示它们,用方法 URI.toURL 和 URL.toURI 在一个和其他.

在Java中,URL和URI的主要区别是一个URL带有可解析的期望,一些应用程序可能需要来自的 InputStream; URI 更像是一个抽象的东西 可能 指向某些可解析的东西(并且通常是这样),但它的含义以及如何达到它对上下文和解释更加开放。

Path (java.nio.file, 1.7)

An object that may be used to locate a file in a file system. It will typically represent a system dependent file path.

新文件 API 在路径界面中图标化,比文件 class 可以提供更大的灵活性。 Path 接口是 File class 抽象,并且是 New IO File API 的一部分。 File 必须指向主机平台理解的“文件”,Path 更通用:它 表示 任意 文件系统中的文件(资源)。 =100=]

路径消除了对主机平台文件概念的依赖。它可以是 ZIP 文件中的条目、可通过 FTP 或 SSH-FS 访问的文件、应用程序的多根表示 class 路径,或者实际上可以通过文件系统有意义地表示的任何内容接口及其驱动程序 FileSystemProvider。它将“挂载”文件系统的强大功能带入 Java 应用程序的上下文中。

主机平台通过“默认文件系统”表示;当您调用 File.toPath 时,您会在默认文件系统上获得一个路径。


Now, if I have a locator that references a class or package in a jar file, will those two (i.e. path an file strings) differ?

不太可能。如果 jar 文件在本地文件系统上,则不应有查询组件,因此 URL.getPathURL.getFile 应该 return 相同的结果。但是,请选择您需要的那个:file-URLs 通常可能没有查询组件,但我肯定可以添加一个。

Lastly - and most importantly - why do I need File object; why isn't a Resource (URL) enough?

URL 可能还不够,因为 File 使您可以访问管理数据,例如权限(可读、可写、可执行)、文件类型(我是目录吗?)以及搜索和操作的能力本地文件系统。如果这些是您需要的功能,则文件或路径提供它们。

如果您有权访问路径,则不需要文件。不过,一些较旧的 API 可能需要文件。

(And is there a Resource object?)

不,没有。有很多类似的东西,但它们不是 ClassLoader.getResource.

意义上的资源