如何在运行时获取Java应用程序的真实路径?

48

我正在创建一个Java应用程序,使用log4j进行日志记录。我已经给出了log4j配置文件的绝对路径,以及生成的日志文件的绝对路径(这些日志文件的位置)。我可以在运行时通过以下方式获得Java web应用程序的绝对路径:

String prefix =  getServletContext().getRealPath("/");

但在普通Java应用程序的上下文中,我们可以使用什么?

15个回答

58

试试;

String path = new File(".").getCanonicalPath();

20
还有System.getProperty("user.dir"),它不会抛出IOException - Jonathan
12
这段代码确实返回应用程序安装的目录吗?看起来应该返回当前工作目录,但这两者并不一定相同。 - Harry Johnston
8
经测试,它返回的是工作目录而不是应用程序所在的目录。 - Ben Jaguar Marshall

37

我不清楚你的问题是什么。如果getServletContext().getRealPath()不是答案,那么“关于我们正在使用的Web应用程序”是什么意思,不清楚。

  • 当前用户的工作目录由System.getProperty("user.dir")给出。
  • 当前用户的主目录由System.getProperty("user.home")给出。
  • 给定当前类所在的JAR文件位置的代码源是this.getClass().getProtectionDomain().getCodeSource().getLocation()

2
@Gary 在发帖之前,你有查看文档吗?这是当前工作目录。user.home 是用户的主目录。 - Jonathan
@Jonathan 抱歉,你是对的,我是错的。可能是今天喝了太多咖啡! - Gary
1
我正在点赞这个。 虽然这篇帖子没有解决我的问题,但是这段代码正是我项目所需要的。(获取正在运行的Java应用程序的路径并将其添加到java.path -我的dll始终在此路径中-) 谢谢。 - yuceel

11

那么使用this.getClass().getProtectionDomain().getCodeSource().getLocation()呢?


7

由于JAR应用程序路径和在IDE中运行的应用程序路径不同,因此我编写了以下代码来始终返回正确的当前目录:

import java.io.File;
import java.net.URISyntaxException;

public class ProgramDirectoryUtilities
{
    private static String getJarName()
    {
        return new File(ProgramDirectoryUtilities.class.getProtectionDomain()
                .getCodeSource()
                .getLocation()
                .getPath())
                .getName();
    }

    private static boolean runningFromJAR()
    {
        String jarName = getJarName();
        return jarName.contains(".jar");
    }

    public static String getProgramDirectory()
    {
        if (runningFromJAR())
        {
            return getCurrentJARDirectory();
        } else
        {
            return getCurrentProjectDirectory();
        }
    }

    private static String getCurrentProjectDirectory()
    {
        return new File("").getAbsolutePath();
    }

    private static String getCurrentJARDirectory()
    {
        try
        {
            return new File(ProgramDirectoryUtilities.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParent();
        } catch (URISyntaxException exception)
        {
            exception.printStackTrace();
        }

        return null;
    }
}

只需调用getProgramDirectory()函数,无论哪种方式,您都应该能够得到良好的结果。


我知道这很老了,但在IDE内运行应用程序和单元测试仍会得到不同的结果。有什么想法吗? - Speedy

4

如果您在谈论一个Web应用程序,您应该使用ServletContext对象的getRealPath方法。

示例:

public class MyServlet extends Servlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp) 
              throws ServletException, IOException{
         String webAppPath = getServletContext().getRealPath("/");
    }
}

希望这能帮到你。

但是在这里,我正在使用简单的Java应用程序。 - Sameek Mishra
@SameekMishra 那你为什么提到了一个Web应用程序? - user207421

2
我使用这种方法来获取jar或exe的完整路径。
File pto = new File(YourClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());

pto.getAbsolutePath());

1
/*****************************************************************************
     * return application path
     * @return
     *****************************************************************************/
    public static String getApplcatonPath(){
        CodeSource codeSource = MainApp.class.getProtectionDomain().getCodeSource();
        File rootPath = null;
        try {
            rootPath = new File(codeSource.getLocation().toURI().getPath());
        } catch (URISyntaxException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }           
        return rootPath.getParentFile().getPath();
    }//end of getApplcatonPath()

2
如果出现URISyntaxException,此代码将抛出NullPointerException异常。 - user207421
这将不会抛出NullPointerException。 - Mihir Patel
1
当然会抛出NPE异常。rootPath为空且在异常情况下永远不会改变,然后您对其进行了取消引用操作。如果您想辩论,请提供事实或论据,而不仅仅是否认。 - user207421

1
new File(".").getAbsolutePath()

1
返回工作目录而不是应用程序目录。 因此,当按下文件打开应用程序时,我们会获取错误的应用程序路径。 - Chameleon

1

最好将文件保存在用户主目录的子目录中,而不是应用程序可能存在的任何位置。

Sun公司花费了相当大的力气来确保使用Java Web Start启动的小程序和应用程序无法确定应用程序的真实路径。这种改变破坏了许多应用程序。如果这些更改被扩展到其他应用程序,我也不会感到惊讶。


0
如果您想获取Java Web应用程序(如Spring Servlet)的真实路径,可以从HttpServletRequest附带的Servlet上下文对象中获取。
@GetMapping("/")
public String index(ModelMap m, HttpServletRequest request) {
    String realPath = request.getServletContext().getRealPath("/");
    System.out.println(realPath);
    return "index";
}

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