简体   繁体   English

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

[英]Absolute Path of Project's folder in Java

Lots of confusion in this topic. 这个主题有很多混乱。 Several Questions have been asked. 有人问过几个问题。 Things still seem unclear. 事情似乎还不清楚。 ClassLoader, Absolute File Paths etc etc ClassLoader,绝对文件路径等

Suppose I have a project directory structure as, 假设我有一个项目目录结构,

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

I have a resource say "txtfile.txt" in "lib/txt" directory. 我在“lib / txt”目录中有一个资源说“txtfile.txt”。 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" 所以我可以将路径编码为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. 假设我从'dist'文件夹执行最后的'prj.jar',该文件夹还包含“lib / txt / txtfile.txt”目录结构和资源,它也应该在这里工作。 I should absolute path of dist folder. 我应该是dist文件夹的绝对路径。

Hope the problem is clear. 希望问题很清楚。

You should really be using getResource() or getResourceAsStream() using your class loader for this sort of thing. 您应该使用类加载器来使用getResource()getResourceAsStream()来实现此类操作。 In particular, these methods use your ClassLoader to determine the search context for resources within your project. 特别是,这些方法使用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). 澄清:而不是考虑如何获取资源的路径,而应该考虑获取资源 - 在这种情况下是某个目录中的文件(可能在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. 在这种情况下,没有必要知道一些绝对路径,只有一些URL来获取文件,ClassLoader将为您返回此URL。 If you want to open a stream to the file you can do this directly without messing around with a URL using getResourceAsStream . 如果要打开文件流,可以直接执行此操作,而无需使用getResourceAsStream来处理URL。

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). 您尝试通过ClassLoader访问的资源需要位于Class-Path(在JAR文件的Manifest中配置)。 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. ClassLoader使用Class-Path来查找资源,因此如果在Class-Path中没有提供足够的上下文,它将无法找到任何内容。 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应解决JAR内部或外部的任何问题,具体取决于您如何引用资源,尽管您当然可以更具体。

Referring to the resource prefixed with a . 参考前缀为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. 将导致ClassLoader也在JAR之外查找文件,而不为资源路径添加句点前缀将指示ClassLoader仅在JAR文件内查找。

That means if you have some file inside the JAR in a directory lib with name foo.txt and you want to get the resource then you'd run getResource("lib/foo.txt"); 这意味着,如果你有一个目录中的JAR 里面的一些文件lib与名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");

First, make sure the lib directory is in your classpath. 首先,确保lib目录位于类路径中。 You can do this by adding the command line parameter in your startup script: 您可以通过在启动脚本中添加命令行参数来执行此操作:

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

save this as MyProject/start.sh or any os dependent script. 将其保存为MyProject / start.sh或任何os依赖脚本。

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");

@Mark is correct. @Mark是正确的。 That is by far the simplest and most robust approach. 这是迄今为止最简单,最强大的方法。

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, 将系统属性“java.class.path”的内容转换为路径名列表,
  • identify the JAR pathname in the list based on its filename, 根据文件名识别列表中的JAR路径名,
  • figure out what "../.." is relative to the JAR pathname to give you the "project" directory, and 弄清楚“../ ..”是什么相对于JAR路径名给你“项目”目录,和
  • build your target path relative to the project directory. 构建相对于项目目录的目标路径。

Another alternative is to embed the project directory name in a wrapper script and set it as a system property using a -D option. 另一种方法是将项目目录名称嵌入到包装器脚本中,并使用-D选项将其设置为系统属性。 It is also possible to have a wrapper script figure out its own absolute pathname; 也可以让包装器脚本找出自己的绝对路径名; eg using whence . 例如,使用whence

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

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