如何访问Java中调用程序的资源目录

如何访问Java中调用程序的资源目录,java,jar,classloader,Java,Jar,Classloader,我有一个程序使用的库。此库在resources文件夹中加载一个特殊目录 在图书馆里我有这个方法 public class DataRegistry{ public static File getSpecialDirectory(){ String resourceName = Thread.currentThread().getContextClassLoader().getResource("data").getFile().replace("%20", " ");

我有一个程序使用的库。此库在resources文件夹中加载一个特殊目录

在图书馆里我有这个方法

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());
}
当我在数据程序中的junit测试中执行getSpecialDirectory时,资源被获取,一切正常

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

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

为清楚起见:

图书馆 本文件第15行:

用法 本文件第31行:

我的POM可能与此有关,因此共享它们可能很重要:\

图书馆

用法

您想要加载Java程序的目录吗?可以试试

文件f=新文件..getCanconicalFile

或者,如果需要所有位置,可以尝试从System.env解析类路径,或者使用默认类加载器

如果您想要一个相对于从中加载类的jar的目录:Quoting from

URL classesRootDir=getClass.getProtectionDomain.getCodeSource.getLocation

上面返回加载.class时使用的基本目录 文件夹。它不包含包。它包含类路径 仅目录。例如,在控制台应用程序中 返回如下内容:

文件:/C:/Documents%20和%20设置/Administrator/workspace/TestPrj/bin/

在Web应用程序中,它返回如下内容:

文件:/C:/Tomcat/webapps/MyApp/WEB-INF/classes/

仅供参考,如果运行程序的用户id无法读取所有文件夹,则此选项可能适用:

或者将调用类的.class对象作为参数传递,并获取其类加载器 您想要加载Java程序的目录吗?可以试试

文件f=新文件..getCanconicalFile

或者,如果需要所有位置,可以尝试从System.env解析类路径,或者使用默认类加载器

如果您想要一个相对于从中加载类的jar的目录:Quoting from

URL classesRootDir=getClass.getProtectionDomain.getCodeSource.getLocation

上面返回加载.class时使用的基本目录 文件夹。它不包含包。它包含类路径 仅目录。例如,在控制台应用程序中 返回如下内容:

文件:/C:/Documents%20和%20设置/Administrator/workspace/TestPrj/bin/

在Web应用程序中,它返回如下内容:

文件:/C:/Tomcat/webapps/MyApp/WEB-INF/classes/

仅供参考,如果运行程序的用户id无法读取所有文件夹,则此选项可能适用:

或者将调用类的.class对象作为参数传递,并获取其类加载器
虽然user@tgkprog是正确的,他的答案是正确的,但我很难想象你真的想要你似乎已经要求的东西,以及他在3中正确回答的东西。请编辑您的问题并解释

如果resourceName将打印到控制台,则输出应该是什么样子, 如果您真的希望JAR文件在我的测试用例中的位置类似于file:/C:/Users/Alexander/.m2/repository/com/clinkworks/neptical/0.0.1-SNAPSHOT/data,这是没有意义的,因为您不想读取甚至写入本地Maven缓存, 或者,您可能更希望直接从JAR文件或任何其他位置(如当前工作目录等)读取资源。
否则我恐怕没有好的方法来回答这个问题。

虽然user@tgkprog是正确的,他的答案是正确的,但我很难想象你真的想要你似乎已经要求的东西,以及他在3中正确回答的东西。请编辑您的问题并解释

如果resourceName将打印到控制台,则输出应该是什么样子, 如果您真的希望JAR文件在我的测试用例中的位置类似于file:/C:/Users/Alexander/.m2/repository/com/clinkworks/neptical/0.0.1-SNAPSHOT/data,这是没有意义的,因为您不想读取甚至写入本地Maven缓存, 或者,您可能更希望直接从JAR文件或任何其他位置(如当前工作目录等)读取资源。 否则恐怕没有好办法回答这个问题

Maven使用target/classes和target/testclasses目录组成用于运行单元测试的类路径。src/main/resources和src/test/resources的内容与编译的java源文件.class文件一起复制到这些位置。 返回一个。 在单元测试情况下,ClassLoader.getResource返回一个文件://schemed URL,代码正常工作 正如所料。 当代码打包在jar文件中执行时,ClassLoader.getResource不再返回file://schemed URL。它不能这样做,因为资源在文件系统中不再是一个单独的实体——它被隐藏在jar文件中。您实际得到的是一个jar:file://schemed URL。 jar:URL不能通过[java.io.File]对象访问。 如果您只需要阅读资源的内容,您应该使用并阅读该资源的内容

请注意,不可能更新类装入器资源的内容

Maven使用target/classes和target/testclasses目录组成用于运行单元测试的类路径。src/main/resources和src/test/resources的内容与编译的java源文件.class文件一起复制到这些位置。 返回一个。 在单元测试情况下,ClassLoader.getResource返回一个文件://schemed URL,您的代码按预期工作。 当代码打包在jar文件中执行时,ClassLoader.getResource不再返回file://schemed URL。它不能这样做,因为资源在文件系统中不再是一个单独的实体——它被隐藏在jar文件中。您实际得到的是一个jar:file://schemed URL。 jar:URL不能通过[java.io.File]对象访问。 如果您只需要阅读资源的内容,您应该使用并阅读该资源的内容


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

据我所知,不能保证您有一个资源目录。Java提供了获取资源的方法,但是没有任何方法可以轻松获取资源的文件,尽管可以为给定的资源获取文件


如果您的应用程序中需要一个特殊的工作目录,我建议将其作为系统属性、程序参数、web应用程序参数或其他让您知道应用程序文件所在位置的内容传递。您甚至可以使用ZIP文件填充此目录,该文件作为应用程序中的资源,因为Java中的ZIP库确实接受输入流作为参数。

据我所知,不能保证您有一个资源目录。Java提供了获取资源的方法,但是没有任何方法可以轻松获取资源的文件,尽管可以为给定的资源获取文件


如果您的应用程序中需要一个特殊的工作目录,我建议将其作为系统属性、程序参数、web应用程序参数或其他让您知道应用程序文件所在位置的内容传递。您甚至可以使用ZIP文件填充此目录,该文件作为应用程序中的资源,因为Java中的ZIP库确实接受输入流作为参数。

您想实现什么?获取相对于DataMojo类的文件夹的路径?您想获取什么?获取相对于DataMojo类的文件夹的路径?我认为如果您在IDE中运行,它将位于本地maven缓存中。。。在已部署的应用程序中,可以是任何目录,只要您将该路径添加到classpathWell,稳定的解决方案应能在所有环境中工作,而不是假设特定的运行时部署场景-至少没有一个原始海报中没有描述。因此,我的查询需要更详细的解释。我认为如果您在IDE中运行。。。在已部署的应用程序中,可以是任何目录,只要您将该路径添加到classpathWell,稳定的解决方案应能在所有环境中工作,而不是假设特定的运行时部署场景-至少没有一个原始海报中没有描述。因此,我的查询需要更详细的解释。您永远不应该使用java.io.File对象来读取jar资源或web资源的内容。这依赖于应用服务器在部署时爆炸WAR文件,而其中许多根本不这样做。servlet和JDKAPI提供了其他机制来实现这一点。这是如何实现的?getClass.getProtectionDomain.getCodeSource.getLocation可能是一场战争?猜测是否需要检查文件对象是文件还是目录,否则将成为父对象?不知道新文件。这很巧妙,谢谢你。你永远不应该使用java.io.File对象来读取jar资源或web资源的内容。这依赖于应用服务器在部署时爆炸WAR文件,而其中许多根本不这样做。servlet和JDKAPI提供了其他机制来实现这一点。这是如何实现的?getClass.getProtectionDomain.getCodeSource.getLocation可能是一场战争?猜测是否需要检查文件对象是文件还是目录,否则将成为父对象?不知道新文件。这很巧妙,谢谢。我想他想要父文件夹,然后获取与该文件夹相关的其他资源-在名为dataRight的子目录中,这是只读的。。。然而,我的问题是不知道如何阅读
流,但如何获取文件的url。我使用的是maven,按照惯例,我希望库的用户使用maven。Maven编译这些资源,我不想url到jar文件,我想要用户应用程序类根的url。由于库位于一个jar中,我似乎无法找到正确的目录。如果你能帮助我定位那个目录,我将非常乐意接受这个详细的答案。没有文件。没有文件系统。与其传递java.io.File对象,不如传递从j.l.ClassLoader.getResource获取的URL…我认为他想要父文件夹,然后获取与该文件夹相关的其他资源-在名为dataRight的子目录中,这是只读的。。。然而,我的问题不是知道如何读取流,而是如何获取文件的url。我使用的是maven,按照惯例,我希望库的用户使用maven。Maven编译这些资源,我不想url到jar文件,我想要用户应用程序类根的url。由于库位于一个jar中,我似乎无法找到正确的目录。如果你能帮助我定位那个目录,我将非常乐意接受这个详细的答案。没有文件。没有文件系统。传递从j.l.ClassLoader.getResource获取的URL,而不是传递java.io.File对象。。。