繁体   English   中英

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

[英]How to get the real path of Java application at runtime?

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

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

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

试试;

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

不清楚你在问什么。 如果getServletContext().getRealPath()不是答案,我不知道“关于我们正在使用的 Web 应用程序”意味着什么,但是:

  • 当前用户的当前工作目录由System.getProperty("user.dir")
  • 当前用户的主目录由System.getProperty("user.home")
  • 从中加载当前类的 JAR 文件的位置由this.getClass().getProtectionDomain().getCodeSource().getLocation()

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

如果您在谈论 Web 应用程序,则应该使用ServletContext对象中的getRealPath

示例:

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

希望这会有所帮助。

由于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()就可以了。

我使用这种方法来获取 jar 或 exe 的完整路径。

File pto = new File(YourClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());

pto.getAbsolutePath());
/*****************************************************************************
     * 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()
new File(".").getAbsolutePath()

最好将文件保存到 user.home 的子目录中,而不是应用程序的任何位置。 可能居住。

Sun 付出了相当大的努力来确保小程序和应用程序。 使用 Java Web Start 启动无法确定应用程序。 真实路径。 此更改破坏了许多应用程序。 如果更改扩展到其他应用程序,我不会感到惊讶。

如果要获取Spring(Servlet)等java web应用的真实路径,可以从你的HttpServletRequest自带的Servlet Context对象中获取。

@GetMapping("/")
public String index(ModelMap m, HttpServletRequest request) {
    String realPath = request.getServletContext().getRealPath("/");
    System.out.println(realPath);
    return "index";
}

我认为每个人都忽略了这个关键问题。

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

servlet 实例可以位于任意多个节点之一上,并且在技术上根本不需要文件系统。

例如,在 Java EE 容器中,可以从数据库甚至目录服务器加载应用程序。 应用程序的不同部分也可以在不同的节点上运行。 应用程序服务器提供对应用程序外部世界的访问。

如果您必须保持与旧版 log4j 的兼容性,请使用 java.util.logging 或 Apache Commons Logging。 告诉应用服务器日志文件应该放在哪里。

我认为System.getProperty("java.class.path")System.getProperty("path.separator")是更好的方案。 例如:

private final static String JAR_SUFFIX = ".jar";

public static String getJarRuntimePath(){
        String javaClassPath = System.getProperty("java.class.path");
        String pathSeparator = System.getProperty("path.separator");
        if(javaClassPath.contains(pathSeparator)){
            javaClassPath = filePath.substring(0,filePath.indexOf(pathSeparator));
        }else if (javaClassPath.endsWith(JAR_SUFFIX)) {
            javaClassPath = filePath.substring(0, filePath.lastIndexOf(File.separator) + 1);
        }
        File serverLocalConfig = new File(javaClassPath);
        return serverLocalConfig.getAbsolutePath();
}

如果你想使用这个答案: https : //stackoverflow.com/a/4033033/10560907

您必须像这样添加导入语句:

import java.io.File;

在最开始的java源代码中。

像这样的答案: https : //stackoverflow.com/a/43553093/10560907

我的类路径的根目录中有一个文件“cost.ini”。 我的 JAR 文件名为“cost.jar”。

以下代码:

  • 如果我们有 JAR 文件,则获取 JAR 文件所在的目录。
  • 如果我们有 *.class 文件,则采用类的根目录。

try {
    //JDK11: replace "UTF-8" with UTF_8 and remove try-catch
    String rootPath = decode(getSystemResource("cost.ini").getPath()
            .replaceAll("(cost\\.jar!/)?cost\\.ini$|^(file\\:)?/", ""), "UTF-8");
    showMessageDialog(null, rootPath, "rootpath", WARNING_MESSAGE);
} catch(UnsupportedEncodingException e) {}

.getPath()返回的路径具有以下格式:

  • 在 JAR 中: file:/C:/folder1/folder2/cost.jar!/cost.ini
  • 在 *.class: /C:/folder1/folder2/cost.ini

    如果应用程序以 JAR 格式提供,则每次使用File导致异常。

  • 表达式

    new File(".").getAbsolutePath();
    

    将为您提供与 JVM 执行相关的当前工作目录。 但是,JVM 确实通过

    System.getProperty(propertyName); 
    

    界面。 可以在此处找到这些属性的列表。

    这些将允许您以独立于平台的方式引用当前用户目录、临时目录等。

    暂无
    暂无

    声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM