在命令行上运行时,使用getResourceAsStream()的列表文件为空

时间:2017-10-10 18:11:52

标签: java embedded-resource

我试图在应用程序的jar文件中列出特定路径的文件。它在我使用" mvn clean package"构建时有效,但是当我使用" java -jar target / myproject_1.0.jar"在命令行上运行时文件列表为空。基于this suggestion,我正在使用此代码

读取目录内容
    boolean failed = true;
    String schemaLocation = "/xml";
    System.out.println("Scanning folder "+schemaLocation);
    InputStream dirStream = getClass().getResourceAsStream(schemaLocation);
    BufferedReader dirReader = new BufferedReader(new InputStreamReader( dirStream ));
    try{
        String filename = dirReader.readLine();
        while( filename != null ){
            failed = false;
            if( filename.endsWith(".xsd")){
                String fullname = schemaLocation+"/"+filename;
                System.out.println("Loading schema file "+fullname );
                InputStream in = getClass().getResourceAsStream(schemaLocation+"/"+filename);
                readAndProcessSchema(in);
            }
            filename = dirReader.readLine();
        }
    }catch(IOException ex){
        ex.printStackTrace();
    }
    if(failed){
        System.out.println("Fallback enabled.");
        InputStream in = getClass().getResourceAsStream(schemaLocation+"/schema_v1.0.xsd");
        readAndProcessSchema(in);
    }

请注意,流不是null,只是空。并且只有路径列表逻辑失败,因为代码示例末尾的回退代码(读取硬编码的xsd文件名)甚至可以在命令行上运行。我也尝试了MyClass.class.getResourceAsStream("/xml")(基于this suggestion),结果相同。

可能相关的另一个注意事项是xml路径的内容来自我的项目依赖项之一,我无法预测它们将来可能添加的其他文件(因此我需要扫描那条路径)。为了引入这些依赖关系,我使用了来自this post的建议,并且我相信它正在运行,因为jar文件目录似乎包含所有内容:

 $ jar -tvf target/myproject-1.0.jar | grep xml
      0 Tue Oct 10 10:02:28 PDT 2017 xml/
   1999 Tue Oct 10 10:02:28 PDT 2017 xml/schema_v1.0.xsd
   4474 Tue Oct 10 10:02:28 PDT 2017 xml/schema_v2.0.xsd
   5757 Fri Oct 06 16:07:48 PDT 2017 META-INF/maven/com.mycompany/myproject/pom.xml

值得一提的是,它是作为Spring Boot应用程序运行的,使用他们的spring-boot-maven-plugin"重新打包"目标。我不仅要知道现在要解决这个问题,还要了解为什么类路径在Maven单元测试中的工作方式与命令行不同。

2 个答案:

答案 0 :(得分:1)

org.apache.commons.io.IOUtils.toString(getClass().getResourceAsStream("/csv/test.csv"), Charset.forName("UTF-8")))

这是如何在jar文件中访问内部源的示例。

这很棘手,资源的根路径是什么。在IDE中,您可以将某个文件夹(例如webapp / recource)标记为 resource 文件夹。当您构建jar文件时,资源文件夹内容将位于根目录中。因此,如果从 / 启动资源路径,则意味着 jar的根目录(即资源文件夹的根目录)

我不使用相对路径,因此您可以查看open resource with relative path in java以获取有关它的更多信息。

答案 1 :(得分:0)

您的代码正在使用Class#getResourceAsStream,它将使用该类的类加载器。这可能在您的IDE或Maven中有效,但在其他情况下可能无效。

实际上你应该尝试使用线程上下文类加载器Thread.currentThread().getContextClassLoader(),如果失败则回退。

有一个类似的问题Get a list of resources from classpath directory

当然,正如那里建议的那样,你可以使用Spring工具PathMatchingResourcePatternResolver