从文件中读取时的java.net.URL缓存

7

看起来java保存了一些与URL和文件相关的缓存。例如,我在我的类路径中有一个名为“resourcs.txt”的文件,它在一个jar文件中。该文件的内容是:“版本1”。

new java.io.BufferedReader (new java.io.InputStreamReader( new URL("jar", "", "file:test.jar!/resourcs.txt").openConnection().getInputStream())).readLine()

返回 "版本1" (如预期)

我将文件内容更改为“版本2”,再次调用此代码。 但我仍然得到“版本1”

如何清除此“缓存”。

注意:我发现这只在Linux上发生。


1
我敢打赌,这更与它是一个.jar文件有关,而不是使用URL。 - SJuan76
我不确定,这只发生在Linux上。 - Guy Korland
1
有趣。第一个流被正确关闭了吗? - esej
你是否在Java程序运行时交换了jar文件? - Jon Lin
5个回答

8
因为您的URL使用jar协议,所以连接是sun.net.www.protocol.jar.JarURLConnection的一个实例,它利用了sun.net.www.protocol.jar.JarFileFactory中实现的缓存。
源代码确认在URLConnection实现上设置setUseCache(false)将防止使用该缓存。
我对Linux/Windows行为差异的假设:来自URLJarFileCloseController接口的关闭事件通知在Windows上触发得更快,因为它不会喜欢保持文件句柄打开太长时间...

5
其实,简单的答案与sbridges给出的答案非常接近,但是你不能使用“new URLConnection(...)”来实例化URLConnection,因为它是一个抽象类。
你可以这样做:
    URL url = new URL(urlSrt);
    URLConnection con = url.openConnection();
    con.setUseCaches(false);

非常好,谢谢。我认为Java中的资源缓存是一个危险的功能,不是每个人都知道。我试图从URL刷新网络摄像头图像,但总是得到相同的图像。 - Stephan
我正在尝试这个,本以为会成功,但是没有。我感到困惑。在我的情况下,它不是一个JAR URL,并且还使用了BufferedReader - tresf

3
您可以使用以下方法关闭url连接的缓存:
  URLConnection con = new URLConnection(new URL("jar", "", "file:test.jar!/resourcs.txt"));
  con.setUseCaches(false);
  new BufferedReader (new InputStreamReader(con.getInputStream())).readLine();

1

我认为这是一种类加载问题,因为它是jar协议。

尝试将您的jar文件作为zip文件打开。

ZipFile zf = new ZipFile(file);
try {
  InputStream in = zf.getInputStream("resourcs.txt");
  // ... read from 'in' as normal
} finally {
  zf.close();
}

0
如果您正在使用第三方代码,则应该可以使用此代码:
url.openConnection().setDefaultUseCaches(false);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接