我遇到了试图从同一目录读取某些配置文件的代码,其中该类本身的.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);
    }
}

10-05 20:36
查看更多