本主题中有很多混淆。有人问过几个问题。事情似乎还不清楚。 ClassLoader,绝对文件路径等
假设我有一个项目目录结构,
MyProject-- --dist --lib --src --test
我在“lib / txt”目录中有一个资源说“txtfile.txt”。我想以独立于系统的方式访问它。我需要项目的绝对路径。 所以我可以将路径编码为abspath +“/ lib / Dictionary / txtfile.txt”
假设我这样做
java.io.File file = new java.io.File(""); //Dummy file
String abspath=file.getAbsolutePath();
我得到的当前工作目录不一定是项目根目录。
假设我从'dist'文件夹执行最后的'prj.jar',该文件夹也包含“lib / txt / txtfile.txt”目录结构和资源,它也应该在这里工作。我应该是dist文件夹的绝对路径。
希望问题很清楚。
答案 0 :(得分:9)
你真的应该使用getResource()或getResourceAsStream()使用类加载器来做这种事情。特别是,这些方法使用ClassLoader来确定项目中资源的搜索上下文。
指定getClass().getResource("lib/txtfile.txt")
之类的内容以便获取文本文件。
澄清:而不是考虑如何获取资源的路径,而应该考虑获取资源 - 在这种情况下是某个目录中的文件(可能在JAR中)。在这种情况下,没有必要知道一些绝对路径,只有一些URL来获取文件,ClassLoader将为您返回此URL。如果要打开文件流,可以直接执行此操作,而无需使用getResourceAsStream
来处理URL。
您尝试通过ClassLoader访问的资源需要位于Class-Path(在JAR文件的Manifest中配置)。这很关键! ClassLoader使用Class-Path来查找资源,因此如果在Class-Path中没有提供足够的上下文,它将无法找到任何内容。如果你添加.
,ClassLoader应解决JAR内部或外部的任何问题,具体取决于你如何引用资源,尽管你当然可以更具体。
引用前缀为.
的资源将导致ClassLoader也在JAR之外查找文件,而不在资源路径前加上句点将指示ClassLoader仅在JAR文件内查找。
这意味着如果你的里面的文件在名为lib
的目录foo.txt
中的JAR,你想获得资源,那么你就可以运行{{1 }}
如果同一资源在JAR之外,您将运行getResource("lib/foo.txt");
答案 1 :(得分:2)
首先,确保lib目录位于类路径中。您可以通过在启动脚本中添加命令行参数来执行此操作:
$JAVA_HOME/bin/java -classpath .:lib com.example.MyMainClass
将其保存为MyProject / start.sh或任何os依赖脚本。
然后你可以访问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");
答案 2 :(得分:0)
@Mark是正确的。这是迄今为止最简单,最强大的方法。
但是,如果你真的需要File
,那么最好的办法是尝试以下方法:
另一种方法是将项目目录名称嵌入到包装器脚本中,并使用-D选项将其设置为系统属性。也可以让包装器脚本找出自己的绝对路径名;例如使用whence
。