2014-04-24 72 views
1

我有一个程序使用的库。该库在资源文件夹中加载一个特殊的目录。如何访问Java中的调用程序的资源目录

在库

我有方法

public class DataRegistry{ 

    public static File getSpecialDirectory(){ 
     String resourceName = Thread.currentThread().getContextClassLoader().getResource("data").getFile().replace("%20", " "); 
     File file = new File(resourceName); 
     return file; 
    } 

} 
在我的程序

我的主要方法

public static void main(String args[]){ 
    System.out.println(Data.getSpecialDirectory()); 
} 

当我的数据程序内执行getSpecialDirectory()在JUnit测试,该资源被提取并且一切都很好。

当我在数据程序(导入jar)之外的主要方法中执行getSpecialDirectory()时,我得到jars数据目录,而不是执行线程的程序所期望的目录。

我觉得得到父类加载器将解决这个问题......我相信我可能在我的理解这里有一个基本问题。

为清楚:https://gist.github.com/AnthonyClink/11275442

(用法) 行此文件的31: https://gist.github.com/AnthonyClink/11275661

我的劲歌可能有一些做

(库) 行此文件的15它,所以分享它们可能很重要:\

(Library) https://github.com/Clinkworks/Neptical/blob/master/pom.xml

(用法) https://github.com/Clinkworks/Neptical-Maven-Plugin/blob/master/pom.xml

+0

什么是你想acheive?获取相对于DataMojo类的文件夹的路径? – tgkprog

回答

1
  1. 你想在Java程序从加载目录?可以试试

    文件f = new File(“。”)。getCanconicalFile();

  2. 或者,如果你想如果你想相对于从那里您的类加载的jar目录中的所有地方可以尝试解析来自System.env类路径或使用默认的类加载器

  3. :从报价http://www.nakov.com/blog/2008/06/11/finding-the-directory-where-your-java-class-file-is-loaded-from/

    URL classesRootDir = getClass()。getProtectionDomain()。getCodeSource()。getLocation();

以上的回报加载你的.class 文件时使用的基本目录。它不包含软件包。它仅包含类路径 目录。例如,在一个控制台应用程序的上述 返回成才这样的:

文件:/ C:/文件%20于是%20Settings /管理员/工作区/ TestPrj/bin中/

在Web应用它返回成才像这样:

文件:/ C:/ Tomcat的/ webapps /下MyApp的/ WEB-INF /班/

仅供参考,如果运行程序的用户ID不能读取所有文件夹这可能适用:http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getProtectionDomain%28%29

  1. 或通过调用类的一个.class对象作为参数,并得到其类加载器
+1

您永远不应该使用java.io.File对象来读取jar资源或web资源的内容。这依赖于应用程序服务器在部署时爆炸WAR文件 - 而且它们中的许多人根本就没有这样做。 servlet和JDK API为此提供了其他机制。 –

+0

这是怎么回事? “getClass()。getProtectionDomain()。getCodeSource()。getLocation()”可能是一场战争?猜测需要检查文件对象是一个文件还是一个目录,并采取父母? – tgkprog

+0

不知道新的文件(“。”)是非常灵活的谢谢你。 – AnthonyJClink

0

虽然用户@t​​gkprog是正确的,他的回答是正确的,我很难想象你真的想你好像什么(3)中已经询问和正确回答了什么。请编辑您的问题,并解释

  • 输出应该是什么样子,如果resourceName将被打印到控制台,
  • ,如果你真的想要的JAR文件的位置(在我的测试情况下会是这样的文件:/ C:/Users/Alexander/.m2/repository/com/clinkworks/neptical/0.0.1-SNAPSHOT/data,这是没有意义的,因为你不想读取甚至写入本地Maven缓存),
  • 或者您可能更想直接从JAR文件或任何其他位置(如当前工作目录等)读取资源。

否则恐怕没有好的方法来回答这个问题。

+0

我认为这将是在本地Maven的缓存,如果你从IDE内运行......在已部署的应用程序可以是任意目录,只要你加入到classpath中 – tgkprog

+0

那么这条道路,稳定的解决方案应该在所有环境中工作,不要假设一个特定的运行时部署场景 - 至少没有一个原始海报甚至没有描述过。因此我的询问作了更详细的解释。 – kriegaex

5
  1. Maven使用target/classes和target/test-classes目录来编写用于运行单元测试的类路径。将src/main/resources和src/test/resources的内容与编译的java源文件(.class文件)一起复制到这些位置。
  2. java.lang.ClassLoader.getResource返回java.net.URL
  3. 在单元测试的情况下,ClassLoader.getResource返回一个file:// schemed URL,并且您的代码按预期工作。
  4. 当您的代码在打包到jar文件中时执行时,ClassLoader.getResource不再返回文件:// schemed URL。它不能因为资源不再是文件系统中的独立实体 - 它被埋在了jar文件中。你实际得到的是一个jar:file:// schemed URL。
  5. jar:无法通过[java.io.File]对象访问URL。

如果您只需要读取资源的内容,您应该使用java.lang.ClassLoader.getResourceAsStream(...)并从中读取内容。

请注意,不能更新类加载器资源的内容。

+0

我认为他想父文件夹,然后抓住这是相对于该文件夹的一些其他资源 - 在一个子目录称为数据 – tgkprog

+0

+1。关于为什么不能这样做的详细解释。 – Jayan

+0

没错,这是只读......但是我的问题是不知道如何读取数据流,但如何获取文件的URL。我正在使用maven,并且按照惯例我期望图书馆的用户使用maven。 Maven确实编译了这些资源,并且我不想将这些资源链接到jar文件,我想要用户应用程序类root的url。由于图书馆在一个罐子里,我似乎无法瞄准正确的目录。如果您可以帮助我定位该目录,我将非常乐意接受这个详细的答案。 – AnthonyJClink

1

就我所知,无法保证您拥有资源目录。 Java提供获取资源的方法为InputStream,但没有任何方法可以轻松地获取资源的文件,但对于给定的资源可能需要get the URL

如果你需要在你的应用程序中的特殊工作目录,我推荐,作为一个系统属性,程序参数,一个Web应用程序参数,还是其他什么东西,可以让你知道你的应用程序文件通过。您甚至可以使用作为资源包含在您的应用程序中的ZIP文件填充此目录,因为Java中的ZIP库确实接受输入流作为参数。

相关问题