我现在正在看一段Java代码,它采用一个路径作为String并使用来获取其URL URL resource =ClassLoader.getSystemClassLoader().getResource(pathAsString);
,然后调用String path = resource.getPath()
并最终执行new File(path);
。
哦,还有URL url = resource.toURI();
和的电话String file = resource.getFile()
。
我现在很困惑-我猜主要是因为术语。有人可以请我介绍这些差异,还是提供一些指向虚拟模型的材料的链接?尤其是URL的URI和 文件的资源
?对我来说,感觉它们应该分别是同一件事。
getFile()
和之间的区别在 getPath()
这里解释:url.getFile()和getpath()有什么区别?(有趣的是,它们似乎都返回字符串,这可能使我的思想状态大增……)
现在,如果我有一个引用jar文件中的类或包的定位器,这两个(即文件字符串的路径)是否会有所不同?
resource.toString()``jar:file:/C:/path/to/my.jar!/com/example/
毕竟会给你(注意感叹号)。
Java 中 URI 和 URL 之间的区别是前者不对空格进行编码吗?cf.
Java中冲突的文件,URI和URL (此答案很好地解释了这两个术语之间的
一般性概念上的 区别:URI标识和URL定位;
__
最后,也是最重要的是, 为什么我需要File
对象?为什么资源(URL
)不够?(并且有一个Resource对象吗?)
很抱歉,这个问题有点无组织。它只是反映出我的困惑… :)
更新2017-04-12
检查JvR的答案,因为它包含更详尽和准确的解释!
我现在很困惑-我猜主要是因为术语。有人可以请我介绍这些差异,还是提供一些指向虚拟模型的材料的链接?尤其是URL的URI和文件的资源?对我来说,感觉它们应该分别是同一件事。
该术语令人困惑,有时甚至令人困惑,并且主要源于Java作为API和平台随着时间的发展。要了解这些术语如何表示它们的作用,重要的是要认识到影响Java设计的两件事:
向后兼容。 旧html" target="_blank">应用程序应在较新的安装上运行,理想情况下无需修改。这意味着需要在所有较新的版本中维护旧的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类表示可通过平台的本机文件系统访问的资源。它仅包含文件名,因此它实际上是主机平台根据其自身的设置,规则和语法解释的路径(请参阅下文)。
请注意,文件不需要指向本地内容,而仅指向主机平台在文件访问上下文中可以理解的内容,例如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可能需要File。
(并且有一个Resource对象吗?)
不,没有。有很多类似的名称,但是它们并不是的资源ClassLoader.getResource。
请注意,我不认为自己100%有能力回答,但是这里有一些评论:
File
表示可通过文件系统访问的文件或目录URL#getPath
在URL(protocol://host/path?query
)的路径部分上吸气URL#getFile
根据JavaDoc返回 path+query
在Java中,URI
只是用于操纵通用标识符本身的数据结构。
URL
另一方面,它实际上是一个资源定位器,它为您提供了一些功能,可以通过注册的URLStreamHandler
s 实际读取资源。
URL可能导致文件系统资源,并且您可以使用file://
协议为每个文件系统资源构造URL (因此File
<-> URL
关系)。
另请注意,这URL#getFile
与无关java.io.File
。
为什么需要File对象?为什么资源(URL)不够?
够了 仅当您要将资源传递给只能使用文件的某些组件时,才需要从中获取资源File
。但是,并非所有资源URL都可以转换为File
。
还有资源对象吗?
从JRE的角度来看,这只是一个术语。一些框架为您提供了此类(例如Spring的Resource)。
问题内容: 人们谈论URL,URI和URN好像是不同的东西,但是用肉眼看起来是一样的。 它们之间有什么明显区别? 问题答案: URI标识和 URL定位 ; 但是,定位符也是标识符,因此每个URL也是一个URI,但是有些URI并非URL。 例子 罗杰·佩特 这是我的名字,它是一个标识符。它就像一个URI,但不能是URL,因为它不会告诉您有关我的位置或如何与我联系的信息。在这种情况下,仅在美国,也至少
问题内容: 在Java中,您可以使用相同的API,但使用不同的URL协议来加载各种资源: 这很好地将资源的实际加载与需要资源的应用程序分离开来,并且由于URL只是一个字符串,因此资源加载也很容易配置。 是否有使用当前类加载器加载资源的协议?这类似于Jar协议,除了我不需要知道资源来自哪个jar文件或类文件夹。 我当然可以使用来做到这一点,但这需要我使用不同的API,因此需要对现有代码进行更改。我希
我知道: > 从位于类路径中的XML文件加载上下文定义,将上下文定义视为类路径资源。 从文件系统中的XML文件加载上下文定义。 从web应用程序中包含的XML文件加载上下文定义。
问题内容: 尝试在文件和URL之间进行转换时,我得到一些奇怪的行为,尤其是当文件/路径的名称中带有空格时。有没有在两者之间进行转换的安全方法? 我的程序具有文件保存功能,其中实际的“保存”操作委托给需要URL作为参数的外部库。但是,我也希望用户能够选择要保存到的文件。问题是,在文件和URL之间进行转换(使用URI)时,空格显示为“%20”,并弄乱了各种操作。考虑以下代码: 这将返回false(由于
问题内容: 我的App Engine项目的war / WEB-INF文件夹中有一个文件。我在FAQ中读到,您可以在servlet上下文中从那里读取文件。我不知道如何形成资源的路径: 我将如何构造到该资源的路径以与File()一起使用,就像上面一样? 问题答案: 有两种方法可以做到这一点。只要扩展WAR文件(一组文件而不是一个.war文件),就可以使用以下API: http://tomcat.apa
im收到“无法读取输入文件!”在下一段代码中 如果图像与.java文件在同一位置,为什么会发生这种情况呢?