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

我现在正在查看一段Java代码,它将一个路径作为String并使用URL resource = ClassLoader.getSystemClassLoader().getResource(pathAsString);获取其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中的URIURL之间的区别是前者不编码空格吗? 参看 在Java中冲突的文件,URI和URL(这个答案很好地解释了两个术语之间的一般概念上的区别:URI标识和URL定位;)

最后 - 也是最重要的 - 为什么我需要File对象; 为什么不是足够的资源( URL )? (还有一个资源对象?)

对不起,如果这个问题有点无组织; 它只是反映了我的困惑...... :)


UPDATE 2017-04-12检查JvR的答案,因为它包含更详尽和精确的解释!


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

  • File表示可通过文件系统访问的文件或目录
  • 资源是可由应用程序加载的数据对象的通用术语
  • 通常资源是与应用程序/库一起分发的文件,并通过类加载机制加载(当它们驻留在类路径中时)
  • URL#getPathURL#getPath路径部分的getter( protocol://host/path?query
  • 按照JavaDoc的URL#getFile返回path+query
  • 在Java中, URI只是用于操作通用标识符本身的数据结构。

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

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

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


    为什么我需要File对象; 为什么不是足够的资源(URL)?

    这就够了。 只有当你想将资源传递给一些只能使用文件的组件时,你需要从中获取File 。 但是,并非所有资源URL都可以转换为File

    有没有一个资源对象?

    从JRE的角度来看,这只是一个术语。 有些框架为您提供这样的类(例如Spring的资源)。


    我现在完全困惑 - 主要是因为术语,我猜。 有人可以请我通过差异,或提供几个链接到防假材料? 尤其是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。

    File(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.getFile将返回与被引用文件的路径字符串相同的字符串。

    Class.getResource返回一个URL:它比返回File更灵活,并且符合20世纪90年代初想象的系统需求。

    URI(java.net,1.4)

    表示统一资源标识符(URI)参考。

    URI是对URL的一种(轻微)抽象。 URI和URL之间的区别是概念性的,主要是学术性的,但是URI在形式上更好地定义,涵盖了更广泛的用例。 因为URL和URI不是同一个东西,所以引入了一个新类来表示它们,方法URI.toURL和URL.toURI在一个和另一个之间移动。

    在Java中,URL和URI之间的主要区别在于URL 带有可解析的期望,应用程序可能需要InputStream; 一个URI被视为更像是一个抽象的东西,可能指向可解析的东西(通常是),但它的含义和如何达到它更容易接受上下文和解释。

    Path(java.nio.file,1.7)

    可用于在文件系统中查找文件的对象。 它通常代表一个依赖于系统的文件路径。

    在Path界面中图标化的新文件API允许比File类提供更大的灵活性。 Path接口是File类抽象 ,并且是New IO File API的一部分。 在File必须指向主机平台所理解的“文件”的情况下,Path更为通用:它代表任意文件系统中的文件(资源)。

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

    主机平台通过“默认文件系统”来表示; 当你调用File.toPath ,你会在默认文件系统上得到一个Path。


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

    不太可能。 如果jar文件位于本地文件系统上,则不应该有查询组件,所以URL.getPathURL.getFile应该返回相同的结果。 然而,选择你需要的一个:file-URLs可能通常不包含查询组件,但是我可以确定添加一个。

    最后 - 也是最重要的 - 为什么我需要File对象; 为什么不是足够的资源(URL)?

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

    如果您有权访问Path,则不需要File。 不过,一些较旧的API可能需要File。

    (还有一个资源对象?)

    不,没有。 有很多类似的命名,但它们不是ClassLoader.getResource意义上的资源。


    Pavel Horal的回答很好。

    正如他所说,“文件”这个词在URL#getFilejava.io.File有完全不同(实际上不相关)的含义 - 这可能是混淆的一部分。

    只需添加:

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

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

  • 在Java中记住一个File对象并不真正代表“文件”,而是文件的位置(全名,带路径)。 因此, File对象允许您定位(并打开)文件,因为URL允许您访问(并打开)资源。 (Java中没有Resource类来表示资源,但是没有一个可以再次表示一个文件: File不是文件,而是文件的路径)。

  • 链接地址: http://www.djcxy.com/p/12115.html

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

    下一篇: Escape quotes in JavaScript