我的代码在一个JAR文件中运行,比如foo.jar,我需要知道,在代码中,运行的foo.jar在哪个文件夹中。

所以,如果FOO .jar在C:\FOO\中,无论我当前的工作目录是什么,我都想获得这个路径。


当前回答

令人沮丧的是,当您在Eclipse中进行开发时,MyClass.class.getProtectionDomain(). getcodesource (). getlocation()返回/bin目录,这很好,但当您将其编译到jar时,该路径包括/myjarname.jar部分,这为您提供了非法的文件名。

为了让代码既能在ide中工作,又能编译到jar中,我使用了下面这段代码:

URL applicationRootPathURL = getClass().getProtectionDomain().getCodeSource().getLocation();
File applicationRootPath = new File(applicationRootPathURL.getPath());
File myFile;
if(applicationRootPath.isDirectory()){
    myFile = new File(applicationRootPath, "filename");
}
else{
    myFile = new File(applicationRootPath.getParentFile(), "filename");
}

其他回答

如果你从Gnome桌面环境(不是任何脚本或终端)点击运行jar,上面所选的答案是不工作的。

相反,我认为下面的解决方案在任何地方都适用:

    try {
        return URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
    } catch (UnsupportedEncodingException e) {
        return "";
    }

这个方法从存档中的代码中调用,返回.jar文件所在的文件夹。它应该在Windows或Unix中工作。


  private String getJarFolder() {
    String name = this.getClass().getName().replace('.', '/');
    String s = this.getClass().getResource("/" + name + ".class").toString();
    s = s.replace('/', File.separatorChar);
    s = s.substring(0, s.indexOf(".jar")+4);
    s = s.substring(s.lastIndexOf(':')-1);
    return s.substring(0, s.lastIndexOf(File.separatorChar)+1);
  } 

从下面的代码派生:确定是否从JAR运行

对我来说,在Linux、Mac和Windows上都适用的唯一解决方案是:

public static String getJarContainingFolder(Class aclass) throws Exception {
  CodeSource codeSource = aclass.getProtectionDomain().getCodeSource();

  File jarFile;

  if (codeSource.getLocation() != null) {
    jarFile = new File(codeSource.getLocation().toURI());
  }
  else {
    String path = aclass.getResource(aclass.getSimpleName() + ".class").getPath();
    String jarFilePath = path.substring(path.indexOf(":") + 1, path.indexOf("!"));
    jarFilePath = URLDecoder.decode(jarFilePath, "UTF-8");
    jarFile = new File(jarFilePath);
  }
  return jarFile.getParentFile().getAbsolutePath();
}

我很惊讶地发现,最近没有人建议使用Path。以下是引用:“Path类包括各种方法,可用于获取路径信息、访问路径元素、将路径转换为其他形式或提取路径的部分”

因此,一个好的替代方法是获取Path对象为:

Path path = Paths.get(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI());

使用ClassLoader.getResource()来查找当前类的URL。

例如:

package foo;

public class Test
{
    public static void main(String[] args)
    {
        ClassLoader loader = Test.class.getClassLoader();
        System.out.println(loader.getResource("foo/Test.class"));
    }
}

(这个例子来自一个类似的问题。)

要找到该目录,需要手动分解URL。有关jar URL的格式,请参阅JarClassLoader教程。