Java中项目文件夹的绝对路径

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3209901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 17:26:12  来源:igfitidea点击:

Absolute Path of Project's folder in Java

javadeploymentabsolute-path

提问by Nitish Upreti

Lots of confusion in this topic. Several Questions have been asked. Things still seem unclear. ClassLoader, Absolute File Paths etc etc

这个话题有很多困惑。已经问了几个问题。事情似乎还不清楚。类加载器、绝对文件路径等

Suppose I have a project directory structure as,

假设我有一个项目目录结构,

MyProject--
            --dist        
            --lib
            --src
            --test

I have a resource say "txtfile.txt" in "lib/txt" directory. I want to access it in a system independent way. I need the absolute path of the project. So I can code the path as abspath+"/lib/Dictionary/txtfile.txt"

我在“lib/txt”目录中有一个资源说“txtfile.txt”。我想以独立于系统的方式访问它。我需要项目的绝对路径。所以我可以将路径编码为 abspath+"/lib/Dictionary/txtfile.txt"

Suppose I do this

假设我这样做

 java.io.File file = new java.io.File("");   //Dummy file
    String  abspath=file.getAbsolutePath();

I get the current working directory which is not necessarily project root.

我得到当前工作目录,它不一定是项目根目录。

Suppose I execute the final 'prj.jar' from the 'dist' folder which also contains "lib/txt/txtfile.txt" directory structure and resource,It should work here too. I should absolute path of dist folder.

假设我从“dist”文件夹中执行最终的“prj.jar”,该文件夹还包含“lib/txt/txtfile.txt”目录结构和资源,它也应该在这里工作。我应该是 dist 文件夹的绝对路径。

Hope the problem is clear.

希望问题很清楚。

采纳答案by Mark Elliot

You should really be using getResource()or getResourceAsStream()using your class loader for this sort of thing. In particular, these methods use your ClassLoader to determine the search context for resources within your project.

你真的应该使用getResource()getResourceAsStream()使用你的类加载器来处理这类事情。特别是,这些方法使用您的 ClassLoader 来确定项目中资源的搜索上下文。

Specify something like getClass().getResource("lib/txtfile.txt")in order to pick up the text file.

指定类似getClass().getResource("lib/txtfile.txt")的内容以获取文本文件。

To clarify: instead of thinking about how to get the path of the resource you ought to be thinking about getting the resource -- in this case a file in a directory somewhere (possibly inside your JAR). It's not necessary to know some absolute path in this case, only some URL to get at the file, and the ClassLoader will return this URL for you. If you want to open a stream to the file you can do this directly without messing around with a URL using getResourceAsStream.

澄清一下:与其考虑如何获取资源的路径,不如考虑获取资源——在这种情况下,某个目录中的文件(可能在您的 JAR 中)。在这种情况下不需要知道一些绝对路径,只需要一些 URL 来获取文件,ClassLoader 会为你返回这个 URL。如果您想打开文件的流,您可以直接执行此操作,而无需使用getResourceAsStream.

The resources you're trying to access through the ClassLoader need to be on the Class-Path (configured in the Manifest of your JAR file). This is critical! The ClassLoader uses the Class-Path to find the resources, so if you don't provide enough context in the Class-Path it won't be able to find anything. If you add .the ClassLoader should resolve anything inside or outside of the JAR depending on how you refer to the resource, though you can certainly be more specific.

您尝试通过 ClassLoader 访问的资源需要位于 Class-Path 上(在 JAR 文件的清单中配置)。这很关键!ClassLoader 使用 Class-Path 来查找资源,因此如果您没有在 Class-Path 中提供足够的上下文,它将无法找到任何内容。如果您添加.ClassLoader 应该根据您引用资源的方式解析 JAR 内部或外部的任何内容,尽管您当然可以更具体。

Referring to the resource prefixed with a .will cause the ClassLoader to also look for files outside of the JAR, while not prefixing the resource path with a period will direct the ClassLoader to look only inside the JAR file.

引用以 a 为前缀的资源.将导致 ClassLoader 也查找 JAR 之外的文件,而不使用句点作为资源路径的前缀将指示 ClassLoader 只查找 JAR 文件内部。

That means if you have some file insidethe JAR in a directory libwith name foo.txtand you want to get the resource then you'd run getResource("lib/foo.txt");

这意味着,如果你有一些文件的目录中JARlib与名称foo.txt,你想要得到的资源,那么你会运行getResource("lib/foo.txt");

If the same resource were outside the JAR you'd run getResource("./lib/foo.txt");

如果相同的资源在您运行的 JAR 之外 getResource("./lib/foo.txt");

回答by Stephen C

@Mark is correct. That is by far the simplest and most robust approach.

@Mark 是正确的。这是迄今为止最简单、最可靠的方法。

However, if you really have to have a File, then your best bet is to try the following:

但是,如果您真的必须拥有File,那么最好的办法是尝试以下操作:

  • turn the contents of the System property "java.class.path" into a list of pathnames,
  • identify the JAR pathname in the list based on its filename,
  • figure out what "../.." is relative to the JAR pathname to give you the "project" directory, and
  • build your target path relative to the project directory.
  • 将系统属性“java.class.path”的内容转换为路径名列表,
  • 根据文件名识别列表中的 JAR 路径名,
  • 找出“../..”相对于 JAR 路径名的含义,以便为您提供“项目”目录,以及
  • 构建相对于项目目录的目标路径。

Another alternative is to embed the project directory name in a wrapper script and set it as a system property using a -D option. It is also possible to have a wrapper script figure out its own absolute pathname; e.g. using whence.

另一种替代方法是将项目目录名称嵌入到包装脚本中,并使用 -D 选项将其设置为系统属性。也可以让包装脚本找出自己的绝对路径名;例如使用whence.

回答by naikus

First, make sure the lib directory is in your classpath. You can do this by adding the command line parameter in your startup script:

首先,确保 lib 目录在您的类路径中。您可以通过在启动脚本中添加命令行参数来执行此操作:

$JAVA_HOME/bin/java -classpath .:lib com.example.MyMainClass

save this as MyProject/start.sh or any os dependent script.

将其保存为 MyProject/start.sh 或任何依赖于操作系统的脚本。

Then you can access the textfile.txt (as rightly mentioned by Mark) as:

然后你可以访问 textfile.txt (正如 Mark 正确提到的):

// if you want this as a File
URL res = getClass().getClassLoader().getResource("text/textfile.txt");
File f = new File(res.getFile());

// As InputStream
InputStream in = getClass().getClassLoader()
        .getResourceAsStream("text/textfile.txt");