我现在很困惑-我猜主要是因为术语。有人可以请我介绍这些差异,还是提供一些指向虚拟模型的材料的链接?尤其是URL的URI和文件的资源?对我来说,感觉它们应该分别是同一回事...
该术语令人困惑,有时甚至令人困惑,并且主要源于Java作为API和平台的发展。要了解这些术语如何表示它们的作用,重要的是要认识到影响Java设计的两件事:
- 向后兼容。 旧应用程序应在较新的安装上运行,理想情况下无需修改。这意味着需要在所有较新的版本中维护旧的API(及其名称和术语)。
- 跨平台。 API应该提供其基础平台的可用抽象,无论是操作系统还是浏览器。
我将逐步介绍这些概念以及它们的产生方式。在那之后,我将回答您的其他特定问题,因为在第一部分中我可能不得不提及某些内容。
什么是“资源”?
可以定位和读取的抽象的通用数据。 松散地说,Java使用它来引用“文件”,该文件可能不是文件,但确实表示已命名的数据。 它在Java中没有直接的类或接口表示,但是由于其属性(可定位,可读),它通常由URL表示。
由于Java的早期设计目标之一是在浏览器内部运行,因此它是具有非常有限的权限/特权/安全清除的沙盒应用程序(小程序!),因此Java在文件(某些内容在本地)上产生了明显的(理论上的)区别。文件系统)和资源(需要读取的内容)。 这就是为什么通过ClassLoader.getResource
而不是通过File类来完成与应用程序相关的某些内容(图标,类文件等)的读取的原因。
不幸的是,由于“资源” 在此解释之外也是一个有用的通用术语,因此它也用于命名非常具体的事物(例如,类ResourceBundle,UIResource,Resource),在这种意义上,它们不是资源。
表示资源(通往资源的路径)的主要类是java.nio.file.Path,java.io.File,java.net.URI和java.net.URL。
文件(java.io,1.0)
文件和目录路径名的抽象表示。
File类表示可通过平台的本机文件系统访问的资源。它仅包含文件名,因此它实际上是主机平台根据其自身的设置,规则和语法解释的路径(请参阅下文)。
请注意,File不需要指向本地内容,而仅指向主机平台在文件访问上下文中可以理解的内容,例如Windows中的UNC路径。如果您在操作系统中将ZIP文件作为文件系统挂载,则File会很好地读取其包含的条目。
URL(java.net,1.0)
类URL表示一个统一资源定位符,它是指向万维网上“资源”的指针。资源可以是简单的文件或目录,也可以是对更复杂对象的引用,例如对数据库或搜索引擎的查询。
与资源的概念一致,URL表示该资源的方式与File类表示主机平台中文件的方式相同:作为指向资源的结构化字符串。 URL还包含一种方案,该方案提示如何访问资源(“ file:”为“询问主机平台”),因此允许通过HTTP,FTP,JAR内以及诸如此类来指向资源。
不幸的是,URL带有自己的语法和术语,包括“文件”和“路径”的使用。如果URL是文件URL,则URL.getFile将返回与引用文件的路径字符串相同的字符串。
Class.getResource
返回一个URL:它比返回File更灵活,并且可以满足1990年代初期系统的需求。
URI(java.net,1.4)
表示统一资源标识符(URI)引用。
URI是URL上的(轻微)抽象。 URI和URL之间的区别是概念性的,并且大多是学术性的,但是URI在形式上更好地定义,并且涵盖了更广泛的用例。由于URL和URI是不同的,因此引入了一个新类来表示它们,并使用URI.toURL和URL.toURI方法在彼此之间移动。
在Java中,URL和URI之间的主要区别在于URL 带有可解析的期望,这是应用程序可能需要InputStream的东西;URI更像是一个抽象的东西,它可能指向可解决的东西(通常是这样做的),但是它的含义和实现方式更容易受到上下文和解释的影响。
路径(java.nio.file,1.7)
可用于在文件系统中定位文件的对象。它通常代表系统相关的文件路径。
在Path界面中图标化的新文件API提供了比File类所提供的更大的灵活性。Path接口是File类的抽象,并且是New IO File API的一部分。如主机平台所理解的,File必须指向“文件”,而Path更通用:它表示任意文件系统中的文件(资源)。
Path消除了对主机平台文件概念的依赖。它可以是ZIP文件中的条目,可以通过FTP或SSH-FS访问的文件,应用程序类路径的多根表示形式,或者实际上可以通过FileSystem接口及其驱动程序FileSystemProvider有意义地表示的任何内容。它将“挂载”文件系统的功能带入Java应用程序的上下文中。
主机平台通过“默认文件系统”表示;调用时File.toPath
,您会在默认文件系统上获得一个路径。
现在,如果我有一个引用jar文件中的类或包的定位器,这两个(即文件字符串的路径)是否会有所不同?
不太可能。如果jar文件是本地文件系统上,你不应该有一个查询组件,所以URL.getPath
和URL.getFile
应该返回相同的结果。但是,请选择一个您需要的文件:文件URL通常可能没有查询组件,但是无论如何我肯定可以添加一个。
最后-最重要的是-为什么我需要File对象;为什么资源(URL)不够?
URL可能不够用,因为File使您可以访问内部管理数据,例如权限(可读,可写,可执行),文件类型(我是目录吗?)以及搜索和操作本地文件系统的能力。如果您需要这些功能,则文件或路径将提供它们。
如果可以访问Path,则不需要File。不过,某些较旧的API可能需要文件。
(并且有一个Resource对象吗?)
不,没有。有很多类似的名称,但是它们并不是的资源ClassLoader.getResource
。
Path
从NIO看文件系统:)