在命令行上 运行 时使用 getResourceAsStream() 列出文件为空
Listing files with getResourceAsStream() is empty when run on command line
我正在尝试列出我应用程序的 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);
}
请注意,流不是空的,只是空的。只有路径列表逻辑失败,因为代码示例末尾的回退代码(读取硬编码的 xsd 文件名)甚至在命令行上也能正常工作。我也尝试了 MyClass.class.getResourceAsStream("/xml")
(基于 this suggestion),结果相同。
另一个可能相关的注释是 xml 路径的内容来自我项目的一个依赖项,我无法预测他们将来可能添加哪些额外的文件(因此我需要扫描那条路径)。为了引入这些依赖项,我使用了 this post 的建议,我相信它是有效的,因为 jar 文件 table-of-contents 似乎包含所有内容:
$ 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
可能还值得一提的是,这是 运行ning 作为 Spring 启动应用程序,使用他们的 spring-boot-maven-plugin "repackage" 目标构建.我现在不仅想知道如何解决这个问题,还想知道为什么类路径在 Maven 单元测试中的工作方式与在命令行中的工作方式不同。
您的代码正在使用 Class#getResourceAsStream
,它将使用 class 的 class 加载器。这可能在您的 IDE 或 Maven 中有效,但在其他情况下可能无效。
实际上,您应该尝试使用线程上下文 class 加载程序 Thread.currentThread().getContextClassLoader()
,如果失败则回退。
有个类似的问题Get a list of resources from classpath directory
当然,按照那里的建议,您可以使用 Spring 工具,PathMatchingResourcePatternResolver
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 以获取更多信息。
我正在尝试列出我应用程序的 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);
}
请注意,流不是空的,只是空的。只有路径列表逻辑失败,因为代码示例末尾的回退代码(读取硬编码的 xsd 文件名)甚至在命令行上也能正常工作。我也尝试了 MyClass.class.getResourceAsStream("/xml")
(基于 this suggestion),结果相同。
另一个可能相关的注释是 xml 路径的内容来自我项目的一个依赖项,我无法预测他们将来可能添加哪些额外的文件(因此我需要扫描那条路径)。为了引入这些依赖项,我使用了 this post 的建议,我相信它是有效的,因为 jar 文件 table-of-contents 似乎包含所有内容:
$ 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
可能还值得一提的是,这是 运行ning 作为 Spring 启动应用程序,使用他们的 spring-boot-maven-plugin "repackage" 目标构建.我现在不仅想知道如何解决这个问题,还想知道为什么类路径在 Maven 单元测试中的工作方式与在命令行中的工作方式不同。
您的代码正在使用 Class#getResourceAsStream
,它将使用 class 的 class 加载器。这可能在您的 IDE 或 Maven 中有效,但在其他情况下可能无效。
实际上,您应该尝试使用线程上下文 class 加载程序 Thread.currentThread().getContextClassLoader()
,如果失败则回退。
有个类似的问题Get a list of resources from classpath directory
当然,按照那里的建议,您可以使用 Spring 工具,PathMatchingResourcePatternResolver
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 以获取更多信息。