我现在完全困惑 - 主要是因为术语,我猜。有人可以引导我了解差异,或者提供一些防假材料的链接吗?特别是URI到URL和资源到文件?对我来说,感觉它们应该分别是一回事......
这个术语令人困惑,有时令人困惑,并且主要是从Java作为API和平台随着时间的推移而演变而来的。要理解这些术语的含义,重要的是要认识到影响Java设计的两件事:
-
向后兼容性。旧应用程序应在较新的安装上运行,理想情况下无需修改。这意味着需要通过所有较新版本维护旧的API(及其名称和术语)。
-
跨平台。API应该提供其底层平台的可用抽象,无论是操作系统还是浏览器。
我将介绍这些概念以及它们是如何形成的。在那之后,我会回答你的其他具体问题,因为我可能不得不在第一部分中提到一些东西。
什么是“资源”?
可以定位和读取的抽象通用数据。粗略地说,Java用它来指代一个“文件”,它可能不是一个文件,但确实代表了一段命名的数据。它在Java中没有直接的类或接口表示,但由于其属性(可定位,可读),它通常由URL表示。
因为Java的早期设计目标之一是在浏览器内运行,所以作为一个沙箱应用程序(小程序!)具有非常有限的权限/特权/安全许可,Java在文件(本地文件系统上的东西)和资源(它需要读取的东西)之间有明显的(理论上的)区别。这就是为什么读取与应用程序相关的内容(图标、类文件等)是通过 File 类而不是通过 File 类完成的。ClassLoader.getResource
不幸的是,因为“resource”在这个解释之外也是一个有用的通用术语,它也被用来命名非常具体的东西(例如.class 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将很好地读取其包含的条目。
网址(java.net,1.0)
类 URL 表示统一资源定位器,它是指向万维网上“资源”的指针。资源可以是像文件或目录这样简单的东西,也可以是对更复杂对象的引用,例如对数据库或搜索引擎的查询。
与资源的概念一起,URL 表示该资源的方式与 File 类表示主机平台中的文件的方式相同:作为指向资源的结构化字符串。URL还包含一个方案,该方案提示如何访问资源(“file:”是“询问主机平台”),因此允许通过HTTP,FTP,JAR内部等指向资源。
不幸的是,URL有自己的语法和术语,包括使用“file”和“path”。如果 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更像是一个抽象的thingamajig,它可能指向可解析的东西(通常确实如此),但它的含义以及如何到达它对上下文和解释更加开放。
Path (java.nio.file, 1.7)
可用于在文件系统中查找文件的对象。它通常表示与系统相关的文件路径。
新的文件 API(在 Path 接口中以图标形式显示)提供了比 File 类更大的灵活性。Path 接口是 File 类的抽象,是 New IO File API 的一部分。File必然指向主机平台所理解的“文件”,而Path则更通用:它表示任意文件系统中的文件(资源)。
Path 消除了对主机平台文件概念的依赖。它可以是 ZIP 文件中的条目,也可以是通过 FTP 或 SSH-FS 访问的文件,应用程序类路径的多根表示形式,或者实际上可以通过 FileSystem 接口及其驱动程序 FileSystemProvider 有意义地表示的任何内容。它将“挂载”文件系统的强大功能带入了 Java 应用程序的上下文中。
主机平台通过“默认文件系统”表示;调用 时,您将在默认文件系统上获得一个 Path。File.toPath
现在,如果我有一个定位器引用了jar文件中的类或包,这两者(即路径和文件字符串)会有所不同吗?
不可能。如果 jar 文件位于本地文件系统上,则不应具有查询组件,因此应返回相同的结果。但是,请选择您需要的那个:文件URL通常可能没有查询组件,但我可以肯定添加一个。URL.getPath
URL.getFile
最后 - 也是最重要的 - 为什么我需要File对象;为什么资源(URL)不够?
URL 可能还不够,因为 File 允许您访问内务管理数据,例如权限(可读、可写、可执行)、文件类型(我是目录吗?)以及搜索和操作本地文件系统的能力。如果这些是您需要的功能,则“文件”或“路径”会提供这些功能。
如果您有权访问 Path,则不需要“文件”。但是,一些较旧的API可能需要File。
(是否有 Resource 对象?
没有。有很多类似的东西,但它们不是意义上的资源。ClassLoader.getResource