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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27845223/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 05:08:39  来源:igfitidea点击:

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

javaurlterminology

提问by Christian

I'm looking at a piece of Java code right now, and it takes a path as a String and gets its URL using URL resource = ClassLoader.getSystemClassLoader().getResource(pathAsString);, then calls String path = resource.getPath()and finally executes new File(path);.

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

Oh, and there are also calls to URL url = resource.toURI();and String file = resource.getFile().

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

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...

我现在完全糊涂了——我猜主要是因为术语。有人可以引导我了解这些差异,或提供一些指向防伪材料的链接吗?特别是 URI 到 URL 和资源到文件?对我来说,感觉它们应该是一样的东西,分别......

The difference between getFile()and getPath()is explained here: What's the difference between url.getFile() and getpath()?(Interestingly they both seem to return Strings, which probably adds a whole lot to my state of mind...)

getFile()和之间的区别在getPath()这里解释:url.getFile() 和 getpath() 之间有什么区别?(有趣的是,他们似乎都返回了字符串,这可能让我的心情大为改观……)

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 文件中的类或包的定位器,这两个(即文件字符串的路径)会不同吗?

resource.toString()would give you jar:file:/C:/path/to/my.jar!/com/example/, after all (note the exclamation mark).

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

Is the difference between URIand URLin Javathat the former doesn't encode spaces? Cf. Files, URIs, and URLs conflicting in Java(This answer explains the general, conceptualdifference between the two terms fairly well: URIs identify and URLs locate;)

JavaURIURL的区别是前者不编码空格吗?参见 Java 中的文件、URI 和 URL 冲突(此答案很好地解释了这两个术语之间的一般概念差异:URI 标识和 URL 定位;

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

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

Sorry if this question is a bit unorganized; it just reflects the confusion I have... :)

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

采纳答案by Pavel Horal

UPDATE 2017-04-12Check JvR's answeras it contains more exhaustive and exact explanation!

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



Please note that I do not consider myself 100% competent to answer, but nevertheless here are some comments:

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

  • Filerepresents a file or directory accessible via file system
  • resourceis a generic termfor a data object which can be loaded by the application
    • usually resourcesare files distributed with the application / library and loaded via class-loading mechanism (when they reside on class-path)
  • URL#getPathis getter on the path part of URL (protocol://host/path?query)
  • URL#getFileas per JavaDoc returns path+query
  • File表示可通过文件系统访问的文件或目录
  • 资源是应用程序可以加载的数据对象 的通用术语
    • 通常资源是与应用程序/库一起分发并通过类加载机制加载的文件(当它们驻留在类路径上时)
  • URL#getPath是 URL 路径部分的 getter ( protocol://host/path?query)
  • URL#getFile根据 JavaDoc 返回 path+query

In Java, URIis just a data structure for manipulating the generic identifier itself.

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

URLon the other hand is really a resource locator and offers you features to actually read the resource via registered URLStreamHandlers.

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

URLs can lead to file-system resources and you can construct URL for every file system resource by using file://protocol (hence File<-> URLrelation).

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

Also be aware that that URL#getFileis unrelated to java.io.File.

另请注意,这URL#getFilejava.io.File.



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

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

It is enough. Only if you want to pass the resource to some component which can work only with files, you need to get Filefrom it. However not all resource URLs can be converted to Files.

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

And is there a Resource object?

是否有 Resource 对象?

From the JRE point of view, it's just a term. Some frameworks provide you with such class (e.g. Spring's Resource).

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

回答by Cyphrags

As I understand them, you could categorize them as following:

据我了解,您可以将它们分类如下:

Web-Based: URIs and URLs.

基于 Web:URI 和 URL。

  • URLs: An URL is a definite location on the internt (just a normal webaddress like - stackoverflow.com)
  • URIs: Ever URL is an URI. But URIs can also contain things like "mailto:", so they are also, well some what of a "script" I'd say.
  • 网址:网址是互联网上的一个明确位置(只是一个普通的网址,如 - stackoverflow.com)
  • URIs:Ever URL 是一个 URI。但是 URI 也可以包含诸如“mailto:”之类的内容,因此它们也是,我想说的某种“脚本”。

And local: Resource, Path and Files

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

  • Resource: Resources are files inside your jar. They are used to load files out of jars / containers.
  • Path: A path is basically a string. But it comes with some handy functions to concatenate multiple strings, or add files to a string. It makes sure the path you are building is valid.
  • File: This is a reference to a directory or file. It's used to modify files, open them etc.
  • 资源:资源是 jar 中的文件。它们用于从罐子/容器中加载文件。
  • 路径:路径基本上是一个字符串。但是它带有一些方便的函数来连接多个字符串,或将文件添加到一个字符串中。它确保您正在构建的路径有效。
  • 文件:这是对目录或文件的引用。它用于修改文件,打开它们等。

It would be easier if they would be merged into one class - they are really confusing :D

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

I hope this helps you :)

我希望这可以帮助你 :)

(I just took a look at the documentation - look at docs.oracle.com)

(我只是看了一下文档 - 看看 docs.oracle.com)

回答by Jim W

A File is an abstract representation of an entity in the local filesystem.

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

A path is generally a string indicating the location of a file within a file system. It usually doesn't include the filename. So c:\documents\mystuff\stuff.txt would have a path with the value of of "C:\documents\mystuff" Obviously the format of absolute filenames and paths would vary enormously from filesystem to filesystem.

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

URL is a susbset of URI with URL usually representing resources accessible over http. I don't think there is any sort of ironclad rule about when something has to be a URI vs a URL. URIs are strings in the form of "protocol://resource-identifier" such as bitcoin://params, http://something.com?param=value. Classes like URL generally wrap the string and provide utility methods that String would have no reason to supply.

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

No such thing as Resource, at least not in the sense you're talking about. Just because a method is named getResource doesn't mean it returns an object of type Resource.

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

Ultimately the best way to figure out what a Class's methods do is to create an instance of it in your code, call the methods and then either step through in debug mode or send the results to System.out.

最终找出类的方法做什么的最好方法是在代码中创建它的实例,调用方法,然后在调试模式下逐步执行或将结果发送到 System.out。

回答by leonbloy

Pavel Horal's answeris nice.

帕维尔霍拉尔的回答很好。

As he says, the word "file" has totally different (practically unrelated) meanings in URL#getFilevs java.io.File- may be that's part of the confusion.

正如他所说,“文件”一词在URL#getFilevs 中 具有完全不同的(几乎不相关的)含义java.io.File——这可能是混淆的一部分。

Just to add:

补充一下:

  • A resourcein Java is an abstract concept, a source of data that can be read. The location (or address) of a resource is represented in Java by a URLobject.

  • A resourcecan correspond to a regular file in the local filesystem (specifically, when its URLbegins with file://). But a resource is more general (it can be also some file stored in a jar, or some data to be read from the network, or from memory, or...). And it's also more limited, because a File(besides being other things than a regular file: a directory, a link) can also be created and writen to.

  • Remember in Java a Fileobject does not really represents "a file" but the location (the full name, with path) of a file. So, a Fileobject allows you to locate (and open) a file, as a URLallows you to access (and open) a resource. (There is no Resourceclass in Java to represent a resource, but neither there is one to represent a file! once more : Fileis not a file, it's the path of a file).

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

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

  • 请记住,在 Java 中,File对象并不真正代表“文件”,而是文件的位置(全名和路径)。因此,File对象允许您定位(和打开)文件,就像URL允许您访问(和打开)资源一样。(ResourceJava 中没有表示资源的类,但也没有表示文件的类!再说一次:File不是文件,而是文件的路径)。

回答by JvR

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...

我现在完全糊涂了——我猜主要是因为术语。有人可以引导我了解这些差异,或提供一些指向防伪材料的链接吗?特别是 URI 到 URL 和资源到文件?对我来说,感觉它们应该是一样的东西,分别......

The terminology is confusing and sometimes befuddling, and mostly born from the evolution both of Java as an API and as a platform over time. To understand how these terms came to mean what they do, it is important to recognise two things that influence Java's design:

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

  • Backwards compatibility.Old applications should run on newer installations, ideally without modification. This means that an old API (with its names and terminology) needs to be maintained through all newer versions.
  • Cross-platform.The API should provide a usable abstraction of its underlying platform, whether that be an operating system or a browser.
  • 向后兼容性。旧的应用程序应该在新的安装上运行,最好不要修改。这意味着旧 API(及其名称和术语)需要通过所有新版本进行维护。
  • 跨平台。API 应该提供其底层平台的可用抽象,无论是操作系统还是浏览器。

I'll walk through the concepts and how they came to be. I'll answer your other, specific questions after that, because I may have to refer to something in the first part.

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

What is a "Resource"?

什么是“资源”?

An abstract, generic piece of data that can be located and read.Loosely said, Java uses this to refer to a "file" that may not be a file but does represent a named piece of data. It does not have a direct class or interface representation in Java, but because of its properties (locatable, readable) it is often represented by an URL.

可以定位和读取的抽象通用数据。粗略地说,Java 使用 this 来指代一个“文件”,它可能不是一个文件,但确实代表了一段命名的数据。 它在 Java 中没有直接的类或接口表示,但由于其属性(可定位、可读),它通常由 URL 表示。

Because one of Java's early design goals was to be run inside of a browser, as a sandboxed application (applets!) with very limited rights/privileges/security clearance, Java makes a clear (theoretical) difference between a file (something on the local file system) and a resource (something it needs to read).This is why reading something relative to the application (icons, class files, and so on) is done through ClassLoader.getResourceand not through the File class.

因为 Java 的早期设计目标之一是在浏览器内运行,作为一个沙盒应用程序(小程序!),权限/特权/安全许可非常有限,Java 在文件(本地文件系统)和一个资源(它需要读取的东西)。这就是为什么读取与应用程序相关的内容(图标、类文件等)是通过ClassLoader.getResource而不是通过 File 类完成的。

Unfortunately, because "resource" is also a useful generic term outsideof this interpretation, it is also used to name very specific things (e.g. class ResourceBundle, UIResource, Resource) that are not, in this sense, a resource.

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

The main classes representing (a path to) a resource are java.nio.file.Path, java.io.File, java.net.URI, and java.net.URL.

表示资源(路径)的主要类是java.nio.file.Pathjava.io.Filejava.net.URIjava.net.URL

File(java.io, 1.0)

文件(java.io, 1.0)

An abstract representation of file and directory pathnames.

文件和目录路径名的抽象表示。

The File class represents a resource that is reachable through the platform's native file system. It contains only the name of the file, so it is really more a path (see later) that the host platform interprets according to its own settings, rules, and syntax.

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

Note that File doesn't need to point to something local, just something that the host platform understands in the context of file access, e.g. a UNC path in Windows. If you mount a ZIP file as a file system in your OS, then File will read its contained entries just fine.

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

URL(java.net, 1.0)

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 表示统一资源定位符,即指向万维网上“资源”的指针。资源可以是简单的文件或目录,也可以是对更复杂对象的引用,例如对数据库或搜索引擎的查询。

In tandem with the concept of a resource, the URL represents that resource the same way the File class represents a file in the host platform: as a structured string that points to a resource.URL additionally contains a scheme that hints at how to reach the resource (with "file:" being "ask the host platform"), and so allows pointing at resources through HTTP, FTP, inside a JAR, and whatnot.

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

Unfortunately, URLs come with their own syntax and terminology, including the use of "file" and "path". In case the URL is a file-URL, URL.getFile will return a string identical to the path string of the referenced file.

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

Class.getResourcereturns an URL: it is more flexible than returning File, and it has served the needs of the system as imagined in the early 1990's.

Class.getResource返回一个 URL:它比返回 File 更灵活,并且它已经满足了 1990 年代初期想象的系统需求。

URI(java.net, 1.4)

URI(java.net, 1.4)

Represents a Uniform Resource Identifier (URI) reference.

表示统一资源标识符 (URI) 引用。

URI is a (slight) abstraction over URL.The difference between URI and URL is conceptual and mostly academic, but URI is better defined in a formal sense, and covers a wider range of use cases. Because URL and URI are/were not the same thing, a new class was introduced to represent them, with methods URI.toURL and URL.toURI to move between one and the other.

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

In Java, the main difference between URL and URI is that an URL carries the expectation of being resolvable, something the application might want an InputStream from; an URI is treated more like an abstract thingamajig that mightpoint to something resolvable (and usually does), but what it means and how to reach it are more open to context and interpretation.

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

Path(java.nio.file, 1.7)

路径(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.

可用于在文件系统中定位文件的对象。它通常表示系统相关文件路径。

The new file API, iconified in the Path interface, allows for much greater flexibility than the File class could offer. The Path interface is an abstraction of the File class, and is part of the New IO File API. Where File necessarily points to a "file" as understood by the host platform, Path is more generic: it represents a file (resource) in an arbitraryfile system.

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

Path takes away the reliance on the host platform's concept of a file. It could be an entry in a ZIP file, a file reachable through FTP or SSH-FS, a multi-rooted representation of the application classpath, or really anything that can be meaningfully represented through the FileSystem interface and its driver, FileSystemProvider. It brings the power of "mounting" file systems into the context of a Java application.

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

The host platform is represented through the "default file system"; when you call File.toPath, you get a Path on the default file system.

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



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 文件中的类或包的定位器,这两个(即文件字符串的路径)会不同吗?

Unlikely. If the jar file is on the local file system, you should not have a query component, so URL.getPathand URL.getFileshould return the same result. However, pick the one you need: file-URLs may not typically have query components, but I could sure add one anyway.

不太可能。如果jar文件是本地文件系统上,你不应该有一个查询组件,所以URL.getPathURL.getFile应该返回相同的结果。但是,选择您需要的一个:文件 URL 通常没有查询组件,但我肯定可以添加一个。

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

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

URL might not be enough because File gives you access to housekeeping data such as permissions (readable, writable, executable), file type (am I a directory?), and the ability to search and manipulate the local file system. If these are features you need, then File or Path provide them.

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

You don't need File if you have access to Path. Some older API may require File, though.

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

(And is there a Resource object?)

(是否有 Resource 对象?)

No, there isn't. There are many things named like it, but they are not a resource in the sense of ClassLoader.getResource.

不,没有。像它这样命名的东西有很多,但它们并不是ClassLoader.getResource.