【问题标题】:Get the application's path获取应用的路径
【发布时间】:2008-10-20 11:07:34
【问题描述】:

我最近搜索了如何在 Java 中获取应用程序的目录。我终于找到了答案,但我需要的时间出奇的长,因为搜索这样一个通用术语并不容易。我认为编写一份如何用多种语言实现这一目标的列表是个好主意。

如果您(不)喜欢这个想法,请随意投赞成票/反对票,如果您喜欢,请投稿

澄清:

包含可执行文件的目录当前工作目录(在 Unix 下由pwd 给出)之间有很好的区别。我最初对前者感兴趣,但也可以随意发布确定后者的方法(澄清你的意思)。

【问题讨论】:

  • 路径是什么意思?当前工作目录,还是可执行代码所在的目录?

标签: language-agnostic path


【解决方案1】:

Java 中调用

System.getProperty("user.dir")

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

返回当前工作目录。

的调用
getClass().getProtectionDomain().getCodeSource().getLocation().getPath();

返回包含当前类的 JAR 文件的路径,或者如果您直接从文件系统运行,则返回产生当前类的 CLASSPATH 元素(路径)。

例子:

  1. 您的应用程序位于

     C:\MyJar.jar
    
  2. 打开 shell (cmd.exe) 和 cd 到 C:\test\subdirectory。

  3. 使用命令java -jar C:\MyJar.jar启动应用程序。

  4. 前两个调用返回 'C:\test\subdirectory';第三次调用返回 'C:\MyJar.jar'。

当从文件系统而不是 JAR 文件运行时,结果将是生成的类文件的根路径,例如

c:\eclipse\workspaces\YourProject\bin\

该路径不包括生成的类文件的包目录。

获取应用程序目录的完整示例,不带 .jar 文件名,如果直接从文件系统运行(例如在调试时),则获取类文件的相应路径:

String applicationDir = getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); 

if (applicationDir.endsWith(".jar"))
{
    applicationDir = new File(applicationDir).getParent();
}
// else we already have the correct answer

【讨论】:

  • 正在寻找一种将只读文件放入与 java 类相同的包中的方法... getClass().getProtectionDomain().getCodeSource().getLocation().getPath() 有效完美,谢谢!
  • @fuzzyanalysis 这正是Class.getResource() 的用途。
【解决方案2】:

.NET (C#, VB, ...) 中,您可以查询当前的Assembly 实例以获取其Location。但是,这会附加可执行文件的文件名。以下代码清理路径(using System.IOusing System.Reflection):

Directory.GetParent(Assembly.GetExecutingAssembly().Location)

或者,您可以使用AppDomain 提供的信息来搜索引用的程序集:

System.AppDomain.CurrentDomain.BaseDirectory

VB 允许通过My 命名空间使用另一个快捷方式:

My.Application.Info.DirectoryPath

【讨论】:

  • 您还可以将 Application.StartupPath 用于某些程序。不过,它不适用于 ASP.NET。
  • 其实就是 Application.ExecutablePath
【解决方案3】:

Windows 中,使用 WinAPI 函数 GetModuleFileName()。为模块句柄传入 NULL 以获取当前模块的路径。

【讨论】:

    【解决方案4】:

    Python

    path = os.path.dirname(__file__)
    

    获取当前模块的路径。

    【讨论】:

      【解决方案5】:

      Objective-C Cocoa(Mac OS X,我不知道 iPhone 的特性):

      NSString * applicationPath = [[NSBundle mainBundle] bundlePath];
      

      【讨论】:

      • 在我的 Mac OSX 应用程序中,我正在寻找可执行文件的实际路径(以包含在 plist 中)并使用: NSString *executablePath = [[NSBundle mainBundle] executablePath]; - 还有一个 'executableURL' 版本可以返回 URL 而不是字符串
      【解决方案6】:

      Java 中,有两种方法可以找到应用程序的路径。一种是聘用System.getProperty

      System.getProperty("user.dir");
      

      另一种可能是使用java.io.File

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

      另一种可能是使用反射:

      getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
      

      【讨论】:

      • 请注意,这有点误导/混淆。你引用的三种方法可以给出完全不同的结果!
      • Zarkonnen:你说得对,但正如我原来的帖子所暗示的那样,我不是专家。这是一个社区维基。请随时编辑/更正我的答案!
      • TIP:如果要访问当前工作目录中的文件,通常不需要指定路径,例如:file = new File("file.cfg");只需确保在初始化期间或在应用程序快捷方式处始终将工作目录设置为应用程序的位置。
      • @lepe 不要在启动时设置工作目录,这会产生一些不良后果,例如默认将某些文件选择器对话框指向应用程序的路径,而不是用户选择的工作目录。
      • 最后一种方法的两个主要问题:一个,ProtectionDomain.getCodeSource() can return null。二, URL.getPath() 不返回文件名,它只返回 URL 的(可能转义的)路径部分。 C:\Program Files\ExampleApp 以 URL 形式表示为 file:/C:/Program%20Files/ExampleApp,对于它 getPath() 返回 "/C:/Program%20Files/ExampleApp",显然不存在。将 URL 转换为文件的唯一正确方法是 new File(url.toURI())
      【解决方案7】:

      在 VB6 中,您可以使用 App.Path 属性获取应用程序路径。

      请注意,除非应用程序位于驱动器的根目录中,否则这不会有尾随 \

      在 IDE 中:

      ?App.Path
      C:\Program Files\Microsoft Visual Studio\VB98
      

      【讨论】:

        【解决方案8】:

        .Net中可以使用

        System.IO.Directory.GetCurrentDirectory

        获取应用程序的当前工作目录,具体在VB.NET中可以使用

        My.Application.Info.DirectoryPath

        获取exe的目录。

        【讨论】:

          【解决方案9】:

          德尔福

          在 Windows 应用程序中:

          Unit Forms;
          path := ExtractFilePath(Application.ExeName);
          

          在控制台应用程序中:

          与语言无关,第一个命令行参数是完全限定的可执行文件名:

          Unit System;
          path := ExtractFilePath(ParamStr(0));
          

          【讨论】:

            【解决方案10】:

            Libc
            在 *nix 类型环境中(在 Windows 中也是 Cygwin):

              #include <unistd.h>
            
               char *getcwd(char *buf, size_t size);
            
               char *getwd(char *buf); //deprecated
            
               char *get_current_dir_name(void);
            

            See man page

            【讨论】:

              【解决方案11】:

              Unix

              在 unix 中,可以找到使用环境变量启动的可执行文件的路径。它不一定是绝对路径,因此您需要将当前工作目录(在 shell 中:pwd)和/或 PATH 变量与环境。

              但在 unix 中该值是有限的,例如可执行文件可以通过符号链接调用,并且只有初始链接用于环境变量。一般来说,如果 unix 上的应用程序将其用于任何有趣的事情(例如加载资源),它们就不是很健壮。在 unix 上,通常对事物使用硬编码的位置,例如 /etc 中指定资源位置的配置文件。

              【讨论】:

                【解决方案12】:

                bash 中,'pwd' 命令返回当前工作目录。

                【讨论】:

                【解决方案13】:

                PHP 中:

                <?php
                  echo __DIR__; //same as dirname(__FILE__). will return the directory of the running script
                  echo $_SERVER["DOCUMENT_ROOT"]; // will return the document root directory under which the current script is executing, as defined in the server's configuration file.
                  echo getcwd(); //will return the current working directory (it may differ from the current script location).
                ?>
                

                【讨论】:

                  【解决方案14】:

                  Android

                  getApplicationInfo().dataDir;
                  

                  为了获得 SD 卡,我使用

                  Environment.getExternalStorageDirectory();
                  Environment.getExternalStoragePublicDirectory(String type);
                  

                  后者用于存储特定类型的文件(音频/电影等)。您在 Environment 类中有这些字符串的常量。

                  基本上,与应用程序相关的任何事情都使用 ApplicationInfo 类,而与 SD 卡/外部目录中的数据相关的事情则使用 E​​nvironment 类。

                  文档: ApplicationInfo , Environment

                  【讨论】:

                    【解决方案15】:

                    Tcl

                    当前脚本的路径:

                    set path [info script]
                    

                    Tcl 外壳路径:

                    set path [info nameofexecutable]
                    

                    如果您需要其中任何一个的目录,请执行以下操作:

                    set dir [file dirname $path]
                    

                    获取当前(工作)目录:

                    set dir [pwd]
                    

                    【讨论】:

                      【解决方案16】:

                      Java:

                      在所有系统(Windows、Linux、Mac OS X)上只对我有用:

                      public static File getApplicationDir() 
                      {
                          URL url = ClassLoader.getSystemClassLoader().getResource(".");
                          File applicationDir = null;
                          try {
                              applicationDir = new File(url.toURI());
                          } catch(URISyntaxException e) {
                              applicationDir = new File(url.getPath());
                          }
                      
                          return applicationDir;
                      }
                      

                      【讨论】:

                      • 如果应用程序在 JAR 文件中运行,这将引发 NPE。
                      【解决方案17】:

                      Ruby中,下面的sn -p返回当前源文件的路径:

                      path = File.dirname(__FILE__)
                      

                      【讨论】:

                        【解决方案18】:

                        CFML中有两个函数可以访问脚本的路径:

                        getBaseTemplatePath()
                        getCurrentTemplatePath()
                        

                        调用 getBaseTemplatePath 会返回“基本”脚本的路径 - 即 Web 服务器请求的路径。
                        调用 getCurrentTemplatePath 返回当前脚本的路径 - 即当前正在执行的脚本。

                        两个路径都是绝对路径,并且包含脚本的完整目录+文件名。

                        要仅确定目录,请在结果上使用函数getDirectoryFromPath( ... )

                        因此,要确定应用程序的目录位置,您可以这样做:

                        <cfset Application.Paths.Root = getDirectoryFromPath( getCurrentTemplatePath() ) />
                        

                        onApplicationStart 事件中为您的Application.cfc 提供



                        要确定运行 CFML 引擎的应用服务器所在的路径,您可以使用 cfexecute 访问 shell 命令,因此(请记住上面关于 pwd/etc 的讨论)您可以这样做:

                        Unix:

                        <cfexecute name="pwd"/>
                        

                        对于 Windows,创建一个包含文本 @cdpwd.bat,然后:

                        <cfexecute name="C:\docume~1\myuser\pwd.bat"/>
                        

                        (使用cfexecutevariable属性存储值,而不是输出到屏幕。)

                        【讨论】:

                          【解决方案19】:

                          在 cmd(Microsoft 命令行 shell)中

                          可以用%*获取脚本的名字(可能与pwd相关)

                          这将获取脚本目录:

                          set oldpwd=%cd%
                          cd %0\..
                          set app_dir=%pwd%
                          cd %oldpwd%
                          

                          如果你发现任何错误,你会的。然后请修复或评论。

                          【讨论】:

                            【解决方案20】:

                            我发布了https://github.com/gpakosz/whereami,它解决了 C 中的问题并为您提供:

                            • 当前可执行文件的路径
                            • 当前模块的路径(从共享库调用时与可执行文件的路径不同)。

                            它在 Windows 上使用 GetModuleFileNameW,在 Linux 和 Android 上解析 /proc/self/maps,在 Mac 和 iOS 上使用 _NSGetExecutablePathdladdr

                            【讨论】:

                              【解决方案21】:

                              请注意回答上面关于 Mac OSX 的“20”:如果 JAR 可执行文件通过 OSX JAR BUNDLER 转换为“应用程序”,那么 getClass().getProtectionDomain().getCodeSource().getLocation(); 将不返回应用的当前目录,而是将应用的内部目录结构添加到响应中。应用的内部结构是/theCurrentFolderWhereTheAppReside/Contents/Resources/Java/yourfile

                              也许这是 Java 中的一个小错误。无论如何,必须使用方法一或二来获得正确答案,即使应用程序启动,两者都会提供正确答案,例如通过位于不同文件夹或桌面上的快捷方式。

                              卡尔

                              SoundPimp.com

                              【讨论】:

                                猜你喜欢
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2012-04-08
                                • 2014-11-07
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                相关资源
                                最近更新 更多