原始代码:
public static <T> T getFromFile(String specifiedFile, String defaultClasspathFile, Class<T> expectedClass) {try {ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();Resource[] resources = resolver.getResources(defaultClasspathFile);Resource resource = resources[0];// 获得文件流,因为在jar文件中,不能直接通过文件资源路径拿到文件,但是可以在jar包中拿到文件流String json = readFileResource(resource);return gson.fromJson(json, expectedClass);} catch (Exception e) {throw new DtalentInitException(String.format("Fail to init instance of class[%s] by file specifiedFile[%s], defaultFile[%s]",expectedClass, specifiedFile, defaultClasspathFile), e);}}
private static String readFileResource(Resource resource) throws IOException {byte[] bytes = new byte[1024];StringBuilder buffer = new StringBuilder("");try {if(resource.exists()) {InputStream stream = resource.getInputStream();for (int n; (n = stream.read(bytes)) != -1; ) {buffer.append(new String(bytes, 0, n));}} else {}return buffer.toString();} catch (IOException e) {log.error("Read resource failed.", e);throw e;}}
调用 getFromFile并传入文件路径defaultClasspathFile读取json文件并转为某类的对象
简化代码:
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();Resource[] resources = resolver.getResources(filePath);Resource resource = resources[0];log.info("文件是否存在{}",resource.exists())
场景:
只有当上述代码中的filepath是打到jar包内的文件路径时可用,比如resource下的static文件夹,则传入static/xxxx.json;此时可以读到文件并正常解析;
但是当指定一个非jar包内而是jar所在容器内路径如/opt/conf/xxxx.json时,调用方法时就会报错:FileNotFoundException....cannot be opened because it does not exist at org.springframework.core.io.Classload...
原因:
在Spring框架中,Resource
是用于访问低级资源的接口,例如文件或类路径资源。ResourcePatternResolver
是一个规定了如何解析资源模式的接口。PathMatchingResourcePatternResolver
是一个能解析类路径下的文件,以及文件系统中的文件的ResourcePatternResolver
实现。
当你在使用ResourcePatternResolver
的getResources
方法时,你可以指定一个类路径的模式,例如classpath*:com/example/**/*.xml
,这将匹配所有名为.xml
的文件,这些文件是在com.example
包或其任何子包中。
然而,你提到的问题是“如何指定容器中的文件路径”。这个问题的答案取决于你对“容器中的文件路径”的具体含义。
-
如果你指的是类路径中的资源,那么你可以使用
classpath:
或classpath*:
前缀来指定资源的位置。例如,你可以使用classpath:/templates/mytemplate.txt
来获取类路径中的文件。 -
如果你指的是文件系统中的资源,那么你可以使用
file:
前缀来指定资源的位置。例如,你可以使用file:/etc/config/myconfig.txt
来获取文件系统中的文件。 -
如果你指的是Web应用程序的上下文中的资源,那么你可以使用
ServletContextResource
来获取这些资源。例如,你可以使用servletContext.getResourceAsStream("/WEB-INF/myfile.txt")
来获取/WEB-INF/myfile.txt
文件。
需要注意的是,如果你试图访问的资源不存在,那么当你试图打开一个InputStream
时,你将会得到一个FileNotFoundException
。
最后,如果你在容器中的文件路径是动态的,或者你不能确保这些文件在所有环境中都存在,那么你可能需要使用一个更灵活的方法来访问这些资源,例如使用Java的File
或Path
类,或者使用Spring的ResourceLoader
接口。
所以:若想指定容器内的文件路径,则需要增加:file 前缀,如:file:/opt/conf/xxx.json