我想从我的罐子里像这样读一个资源:
File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferedReader reader = new BufferedReader(new FileReader(file));
//Read the file
当在Eclipse中运行它时,它工作得很好,但如果我将它导出到一个jar,然后运行它,会有一个IllegalArgumentException:
Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical
我真的不知道为什么,但通过一些测试,我发现如果我改变了
file = new File(getClass().getResource("/file.txt").toURI());
to
file = new File(getClass().getResource("/folder/file.txt").toURI());
然后它反过来工作(它在jar中工作,但在eclipse中不工作)。
我正在使用Eclipse,文件所在的文件夹位于类文件夹中。
问题是某些第三方库需要文件路径名而不是输入流。大多数答案都没有提到这个问题。
在这种情况下,一种解决方法是将资源内容复制到临时文件中。下面的例子使用了jUnit的TemporaryFolder。
private List<String> decomposePath(String path){
List<String> reversed = Lists.newArrayList();
File currFile = new File(path);
while(currFile != null){
reversed.add(currFile.getName());
currFile = currFile.getParentFile();
}
return Lists.reverse(reversed);
}
private String writeResourceToFile(String resourceName) throws IOException {
ClassLoader loader = getClass().getClassLoader();
InputStream configStream = loader.getResourceAsStream(resourceName);
List<String> pathComponents = decomposePath(resourceName);
folder.newFolder(pathComponents.subList(0, pathComponents.size() - 1).toArray(new String[0]));
File tmpFile = folder.newFile(resourceName);
Files.copy(configStream, tmpFile.toPath(), REPLACE_EXISTING);
return tmpFile.getAbsolutePath();
}
到目前为止(2017年12月),这是我发现的唯一一个在IDE内部和外部都可以工作的解决方案。
使用PathMatchingResourcePatternResolver
注意:它也适用于spring-boot
在这个例子中,我读取了src/main/resources/my_folder中的一些文件:
try {
// Get all the files under this inner resource folder: my_folder
String scannedPackage = "my_folder/*";
PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver();
Resource[] resources = scanner.getResources(scannedPackage);
if (resources == null || resources.length == 0)
log.warn("Warning: could not find any resources in this scanned package: " + scannedPackage);
else {
for (Resource resource : resources) {
log.info(resource.getFilename());
// Read the file content (I used BufferedReader, but there are other solutions for that):
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
// ...
// ...
}
bufferedReader.close();
}
}
} catch (Exception e) {
throw new Exception("Failed to read the resources folder: " + e.getMessage(), e);
}