gpt4 book ai didi

java - .getClassLoader().getResourceAsStream(path) 缓存结果

转载 作者:行者123 更新时间:2023-12-02 08:13:16 25 4
gpt4 key购买 nike

我在servlet加载文件,使用.getClassLoader().getResourceAsStream(path),路径在WEB-INF/classes目录中,我在更改路径文件内容后发现,但文件servlet加载是相同的,不不改变,文件被缓存。

示例代码:

在我更改 test.key 内容后,此方法每次都会得到相同的结果

private String getKey(String param){
String name = "keys/"+param+"/test.key";
InputStream in = XXXServlet.class.getClassLoader().getResourceAsStream(name);
StringBuilder builder = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = null;
while((line = reader.readLine()) != null){
builder.append(line).append("\n");
}
} catch (IOException ignoreException) {

}finally{
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}

String result = builder.toString();
return result;
}

================================================== =================

修改这两行代码,就可以正常工作了

    String name = "/WEB-INF/classes/keys/"+param+"/test.key";
InputStream in = getServletContext().getResourceAsStream(name);

最佳答案

安库尔是对的。如果名称和关联内容已经被类加载器或其父级加载过一次,则尝试获取类或资源(无论文件/输入流的名称和路径如何)的现有类加载器将永远不会重新加载。这是出于性能原因。唯一的方法是创建类加载器的新实例并再次执行此操作。但是,至少对于类,您将不得不担心在系统中一起运行的不兼容的类。就像您无法将新类的实例分配给使用第一个类加载器实例加载的类键入的变量一样,因为它们在技术上是不同的类。

Pabrantes 认为这是不同的,因为 Liu 并没有加载一个“类”,而是一个键:“keys/”+param+“/test.key”;然而,他使用类加载器来执行此操作,并且关于 getResourceAsStream(name) 加载“name”的规则是相同的。不管它是否是一个类,类加载器都会认为“哦,你走了,我已经加载了‘name’的字节流”。将其从永久根中拉出来。对于那些感兴趣的人 - 如果您创建/实现自己版本的每次都会重新加载的新类加载器 - 只需确保它仅针对非常特定的路径或名称模式执行此操作。另请记住,您加载的每个副本都可能会在 permgen 中获得空间,因此随着时间的推移,permgen 将失去控制,除非您卸载。

所以 - 这就是它不起作用的原因。 ContextLoader很好用。 :-)

丹·C.

关于java - .getClassLoader().getResourceAsStream(path) 缓存结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15376451/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com