Java [Class].Class.getResourceAsStream(…)在某些目录的JAR文件中使用时返回null?
我有一个很奇怪的问题。似乎从JAR文件中加载资源有时有效,有时无效 Jar文件只包括类文件、清单和Java [Class].Class.getResourceAsStream(…)在某些目录的JAR文件中使用时返回null?,java,eclipse,jar,resources,Java,Eclipse,Jar,Resources,我有一个很奇怪的问题。似乎从JAR文件中加载资源有时有效,有时无效 Jar文件只包括类文件、清单和test.txt 当我用Eclipse打包它时,它通常工作得很好(test.txt的内容可以访问),但是在一些目录中,Resourceproblem.class.getResourceAsStream(“/test.txt”)返回null——尽管它是同一个Jar文件 例如,当我双击jar文件\\remotecomputer\folder\subfolder\test.jar时,无法找到jar文件中的
test.txt
当我用Eclipse打包它时,它通常工作得很好(test.txt的内容可以访问),但是在一些目录中,Resourceproblem.class.getResourceAsStream(“/test.txt”)
返回null
——尽管它是同一个Jar文件
例如,当我双击jar文件\\remotecomputer\folder\subfolder\test.jar
时,无法找到jar文件中的test.txt
。但有时,当路径名很长且包含空格(至少在WindowsXPSP3上)时,也会出现这种情况
有什么想法吗
示例代码:
import java.io.*;
import javax.swing.*;
public class Resourceproblem {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Resourceproblem();
}
});
}
private Resourceproblem() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setLocationRelativeTo(null);
JTextArea text = new JTextArea();
text.setEditable(false);
frame.add(text);
frame.setVisible(true);
try {
InputStream in = Resourceproblem.class.getResourceAsStream("/test.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line = br.readLine();
br.close();
in.close();
text.setText(line);
} catch(Exception ex) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
pw.flush();
String s = sw.toString();
pw.close();
ex.printStackTrace();
text.setText(s);
}
}
}
test.txt只是一个文本文件,其中有一行用于检查加载是否成功。我有一个想法,但我对知道您的问题没有信心 我多次使用eclipse从示例源代码创建jar文件;我使用Win7将jar文件存储在c:\local和c:\local\one\two-three\four中 在getResourceAsStream()调用中,我不熟悉在资源文件名前面使用“/”。您的示例程序在每种情况下都可以使用“/”或不使用“/”,但我建议删除它,看看这是否解决了您的问题。在这种情况下,该文件与访问它的类位于同一目录中
我本以为“/”会导致程序在文件系统的根目录中查找文件,但这似乎没有发生…我认为您需要了解访问类加载器的各种方法之间的差异,即和之间的差异。@Boris:这到底是什么意思?当我尝试
Resourceproblem.class.getClassLoader().getResourceAsStream(“/test.txt”)代码>它甚至不再在Eclipse中工作。这意味着您的文件不是您认为的位置。请检查.jar文件中是否确实包含test.txt。.jar文件实际上是一个.zip文件,因此您可以使用任何读取.zip文件的工具打开它。您甚至可以复制它,将副本重命名为具有.zip扩展名,然后使用Windows内置的zip处理程序打开它。@VGR:是的,其中包含test.txt。正如我所写,这在大多数目录中都有效,但在一些“特殊”(?)目录中,它就是不起作用。“我不知道ClassLoader
是如何工作的,所以这里有一个随机猜测”?这不是一个真正的答案/
表示类路径的根,它与jar所在的目录关系不大。“/”仅用于从jar中加载资源。没有它,资源根本无法加载。不——我去掉“/”,创建了jar,在eclipse中运行,用eclipse创建了jar,将jar移动到我提到的两个目录中,然后它从jar中加载了该文件。@rcook:我想我现在终于明白你的意思了。我说的是一个包含类文件和test.txt的JAR文件,而您考虑将test.txt分开,对吗?不,我回答中的“文件系统的根目录”部分可能会误导您。此后,我对此进行了研究,发现对于getResourceAsStream来说,“/”是jar文件的“顶部”,也就是说,如果您查找/a/b/c/test.txt,它应该位于jar中的那些文件夹中。如果您不使用“/”,那么您指定的是与您正在使用的类所在的文件夹/包相关的内容,即使用来自类x.y.z的getResource的“a/b/c/test.txt”。MyClass表示文件位于x/y/z/a/b/c中。