2010-07-09 135 views
3

本主题中存在很多混淆。有人问了几个问题。事情似乎还不清楚。 的ClassLoader,绝对文件路径等等等等Java中项目文件夹的绝对路径

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

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

我有一个资源说,在“LIB/TXT”目录“txtfile.txt”。我想以系统独立的方式访问它。我需要项目的绝对路径。 所以我可以代码路径作为ABSPATH +“/ lib目录/词典/ txtfile.txt”

想我这样做

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

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

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

希望问题清楚。

+0

而且我觉得这种做法仍限于“UNIX”像目录结构平台,追加“/ lib目录/字典/txtfile.txt“在Windows上将由于前向和反向差异而导致混乱! :| – 2010-07-09 04:49:11

+0

实际上,Java并不关心斜杠方向,尽管你只能明确指定非根驱动器,因为'/'指向当前磁盘的根目录。 – 2010-07-09 04:53:09

+0

System.getProperty(“file.separator”)将返回Windows环境的“\”和Unix(和类Unix)的返回值“/”。 – Catchwa 2010-07-09 04:57:41

回答

9

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

为了拿起文本文件指定像getClass().getResource("lib/txtfile.txt")

为了澄清:不是想着如何获取资源的路径,你应该要思考得到的资源 - 在这种情况下,在目录中的文件的地方(也许是你的JAR内)。在这种情况下,不需要知道一些绝对路径,只需要一些URL来获取文件,ClassLoader就会为您返回这个URL。如果你想打开一个文件流,你可以直接使用getResourceAsStream来实现这个功能。

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

引用以.为前缀的资源将导致ClassLoader在JAR之外寻找文件,而不在资源路径的前面添加句点将指示ClassLoader仅在JAR文件内查找。

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

如果相同的资源是该JAR你”之外d运行getResource("./lib/foo.txt");

+0

马克如我所说,我已经尝试过它会上课装载机。你能不能在我的情况下张贴一些关于如何解决它的片段? – 2010-07-09 04:57:22

+0

@MAK我了解这个事实,它必须由类加载器来处理。但是如何? java.net.URL url = getClass()。getResource(“lib/txtfile.txt”); 为我返回一个空的URL! – 2010-07-09 05:03:14

+0

@Mark dist文件夹有一个prj.jar +“lib/txt/txtfile”资源。 (资源在jar外面运行) 我打算在最后tar dist文件夹来发布它 – 2010-07-09 05:12:53

0

@马克是正确的。这是迄今为止最简单和最稳健的方法。

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

  • 打开系统属性“java.class.path”的内容转换成路径的列表,
  • 识别JAR路径基于其文件名列表,
  • 弄清楚什么是“../ ..”是相对于JAR路径给你的‘工程’目录,并
  • 构建目标路径相对于项目目录。

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

2

首先,确保lib目录在您的类路径中。你可以在你的启动脚本添加命令行参数做到这一点:

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

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

然后你就可以访问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");