ClassUtils.getDefaultClassLoader().getResource(“”).getPath() 获取的结果值包含 ‘!’。

huangapple go评论79阅读模式
英文:

ClassUtils.getDefaultClassLoader().getResource("").getPath() the obtained result value contains '!'

问题

当我想要使用 ClassUtils.getDefaultClassLoader().getResource("").getPath() 来获取文件路径时,它返回 *.jar!/BOOT-INF/classes!/*。但实际上文件路径不包含 !。它实际上看起来是 *.jar/BOOT-INF/classes/*

我想知道为什么会这样,以及如何处理这种情况?

英文:

When I want to use ClassUtils.getDefaultClassLoader().getResource("").getPath() to get the file path, it returns *.jar!/BOOT-INF/classes!/*. But actually the file path does not contain !. It just looks like *.jar/BOOT-INF/classes/*.

I want to know why and how to deal with this case?

答案1

得分: 0

你正在请求一个空白资源,这不是一个好主意。请请求一个真实的资源。而且一般情况下,不要请求“默认类加载器”,因为你不知道它可能是什么,请请求你知道的类的加载器。例如:

public class Example {
    void foo() {
        URL resource = Example.class.getResource("Example.class");
    }
}

这是一个类,询问自己的类文件在哪里;它在所有情况下都可以工作,即使是在代理环境中也是如此。

其次,“类路径资源”的要点是它们是由类加载器提供的东西。ClassLoader 是一个 API(也就是说,任何人都可以编写实现;它就像一个接口),它要求你提供以下工具:

  1. 根据资源的名称,你必须能够以 URL 形式和 InputStream 形式返回所有匹配的条目。

就是这样。没有第二点。特别要注意的是,当请求一个空白资源时,没有必要提供任何有意义的内容,不能要求类加载器列出它可以提供的所有资源,而且它提供的资源不一定是文件。

事实上,通常情况下它们不是文件。

在这种情况下,你获取的资源是 jar 文件中的某个条目,它不是文件,因此不是 Path,并且在它上面调用 .getPath() 是毫无意义的,会返回无用的垃圾。

解决方案是意识到将通用资源转换为路径是不可能的。

所以,让我们退一步:你有一个未明示的问题 X,并且认为:“我知道了!我会请求一个空白资源,将其转换为路径,然后解决我的问题!”-但现在你对此有疑问。但问题是,无论 X 是什么,那都不是正确的解决方案。

你之所以会得到感叹号是因为 jar 文件中的资源的 URL 如下所示:

jar:file://absolute/path/to/jarfile.jar!/entryname/in/jar.class

例如。! 分隔“jar 文件的路径”和“jar 文件内资源的路径”。没有办法将这些内容直接转换为 java.io.Filejava.nio.file.Path 实例,因为…… jar 文件中的条目本身并不是文件。

英文:

You're asking for a blank resource, that's not a good idea. Ask for an actual, real resource. And, generally, don't ask the 'default class loader', because you have no idea what that might be, ask for the loader of a class you know. For example:

public class Example {
    void foo() {
        URL resource = Example.class.getResource("Example.class");
    }
}

This is a class, asking where its own class file is; works in all cases, even exotic ones, such as when we're in an agent environment.

Secondarily, the point of 'classpath resources' is that they are things provided by a class loader. The ClassLoader is an API (as in, anybody can write an implementation; it's like an interface), which demands that you provide the following tooling:

  1. Given the name of a resource, you must be able to return all matching entries, in both 'URL' form, as well as in InputStream form.

That's it. There is #2. In particular, there is no need to serve anything sensible when asking for a blank resource, it is not possible to ask a classloader to list all resources it can serve, and the resources it serves do not have to be files.

In fact, usually, they aren't.

In this case, the resource you are getting is for some entry in a jar file, which isn't a file, and thus, isn't a Path, and thus, calling .getPath() on it, is nonsensical, and returns useless garbage.

The solution is to realize that it is impossible to turn a general resource into a path.

So, let's take a step back: You had some unstated problem X and thought: I know! I'll ask for the blank resource, turn that into a path, and that solves my problem! - but now you have questions about that. But the problem is, that was not the right solution to whatever X is.

The reason you're getting an ! is because the URL for a resource inside a jar file looks like:

jar:file://absolute/path/to/jarfile.jar!/entryname/in/jar.class

for example. The ! separates 'path to the jar' from 'path of the resource inside the jar'. There is no way to turn any of this straight into a java.io.File or java.nio.file.Path instance because... entries in jar files aren't themselves files.

huangapple
  • 本文由 发表于 2020年8月14日 10:54:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/63405864.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定