我遇到了试图从同一目录读取某些配置文件的代码,其中该类本身的.class文件是:
File[] configFiles = new File(
this.getClass().getResource(".").getPath()).listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".xml");
}
});
显然,这在某些情况下可行(也许在Resin内部运行代码时),但是对我来说,运行Tomcat时,它对NPE完全失败,因为
getClass().getResource(".")
返回null
。一位同事建议创建另一个配置文件,其中包含所有“.xml”配置文件的列表(确实可以在这里使用,因为它保持静态),因此您不应该真正尝试在Java中执行类似的操作。
还是,我想知道是否有某种通用的通用方法可以获取给定.class文件所在目录的路径?我想您可以从.class文件本身的路径中获取它,如下所示:
new File(this.getClass().getResource("MyClass.class").getPath()).getParent()
...但这是唯一/最干净的方法吗?
编辑:为澄清起见,假设我们知道此代码已部署在应用程序中,这样,将始终从磁盘上的.class文件读取MyClass.class,并且资源将位于同一目录中。
最佳答案
我知道这个线程很旧,但是它是Google搜索的最佳结果,对我来说,这里没有令人满意的答案。这是我编写的一些代码,对我来说非常有用。当然,需要注意的是,它可能尚未从磁盘加载,但它说明了这一点,在这种情况下返回null。这对于查找“容器”(即类的根位置,无论是jar还是文件夹)都很好。这可能无法直接满足您的需求。如果没有,请随意删除您需要的代码部分。
/**
* Returns the container url for this class. This varies based on whether or
* not the class files are in a zip/jar or not, so this method standardizes
* that. The method may return null, if the class is a dynamically generated
* class (perhaps with asm, or a proxy class)
*
* @param c The class to find the container for
* @return
*/
public static String GetClassContainer(Class c) {
if (c == null) {
throw new NullPointerException("The Class passed to this method may not be null");
}
try {
while(c.isMemberClass() || c.isAnonymousClass()){
c = c.getEnclosingClass(); //Get the actual enclosing file
}
if (c.getProtectionDomain().getCodeSource() == null) {
//This is a proxy or other dynamically generated class, and has no physical container,
//so just return null.
return null;
}
String packageRoot;
try {
//This is the full path to THIS file, but we need to get the package root.
String thisClass = c.getResource(c.getSimpleName() + ".class").toString();
packageRoot = StringUtils.replaceLast(thisClass, Pattern.quote(c.getName().replaceAll("\\.", "/") + ".class"), "");
if(packageRoot.endsWith("!/")){
packageRoot = StringUtils.replaceLast(packageRoot, "!/", "");
}
} catch (Exception e) {
//Hmm, ok, try this then
packageRoot = c.getProtectionDomain().getCodeSource().getLocation().toString();
}
packageRoot = URLDecoder.decode(packageRoot, "UTF-8");
return packageRoot;
} catch (Exception e) {
throw new RuntimeException("While interrogating " + c.getName() + ", an unexpected exception was thrown.", e);
}
}