1.为什么@Resource出错
2.java 代码里读取jar包下resources目录下的源码文件
为什么@Resource出错
看spring2.0源码中的 InputStreamResource类中的isOpen() 方法:
/
*** This implementation always returns <code>true</code>.
*/
public boolean isOpen() {
return true;
}
这个方法永远返回true。
再看这个方法:
/
*** Detects which kind of validation to perform on the XML file identified
* by the supplied { @link Resource}. If the
* file has a <code>DOCTYPE</code> definition then DTD validation is 源码used
* otherwise XSD validation is assumed.
*/
protected int detectValidationMode(Resource resource) {
if (resource.isOpen()) {
throw new BeanDefinitionStoreException(
"Passed-in Resource [" + resource + "] contains an open stream: " +
"cannot determine validation mode automatically. Either pass in a Resource " +
"that is able to create fresh streams, or explicitly specify the validationMode " +
"on your XmlBeanDefinitionReader instance.");
}
... ...
}
由于resource.isOpen()永远返回true,所以这里会抛出异常。源码我的源码理解是:InputStreamResource是直指向输入流InputStream的,在构造InputStreamResource时,源码我们要加载的源码云商商城源码资源第一次被打开后, 即InputStreamResource的源码getInputStream()方法调用后, 不允许再次读取资源对应的源码InputStream。下面是源码getInputStream()方法,可以看到,源码InputStreamResource用私有的源码属性 read来标记输入流是否被读取过, 若读取过一次,源码 再次读取会抛异常的源码。
/
*** This 源码implementation throws IllegalStateException if attempting to
* read the underlying stream multiple times.
*/
public InputStream getInputStream() throws IOException, IllegalStateException {
if (this.read) {
throw new IllegalStateException("InputStream has already been read - " +
"do not use InputStreamResource if a stream needs to be read multiple times");
}
this.read = true;
return this.inputStream;
}
然而从spring2.0开始,为了支持xml schema,源码需要再次读取资源以检查配置文件是否遵循了DTD 和 xml schema, 又由于当前被打开的USDT代收源码资源不能被多次读取, 以致异常抛出。从下面spring源码中关于InputStreamResource类的说明中可以看到,作者强烈建议不要使用InputStreamResource, 而是尽量使用替代者ByteArrayResource、ClassPathResource、FileSystemResource、UrlResource等来加载xml等资源。
InputStreamResource类是vue静态源码为给定的InputStream而准备的Resource接口的实现。它只有在没有其它合适的Resource接口实现类可用时才使用。而且,只要有可能就尽量使用ByteArrayResource或者其它基于文件的Resource实现。与其它Resource实现不同的是,这是个已经打开资源的描述符(因此isOpen()函数返回 true)。如果你需要在其它位置保持这个资源的描述符或者多次读取一个流,请不要使用它。
/
*** { @link Resource} implementation for a given InputStream. Should only
* be used if no specific Resource implementation is unreal源码修改applicable.
* In particular, prefer { @link ByteArrayResource} or any of the
* file-based Resource implementations where possible.
*
* <p>In contrast to other Resource implementations, this is a descriptor
* for an <i>already opened</i> resource - therefore returning "true" from
* <code>isOpen()</code>. Do not use it if you need to keep the resource
* descriptor somewhere, or if you need to read a stream multiple times.
*
* @author Juergen Hoeller
* @since ..
* @see ByteArrayResource
* @see ClassPathResource
* @see FileSystemResource
* @see UrlResource
*/
public class InputStreamResource extends AbstractResource { ...}
引一段springsource站网友的解释, 供参考:
This is caused by Spring 2.0's new support for XML schema: We need to sneak into the file to find out whether it's based on our DTD or our schema now. Simply assuming the DTD as default in that case could cause strange exceptions in the XML parser that would only arise with such an InputStream specified.
The recommended solution is the same as the general resource loading recommendation of the past two years:Do not use InputStreamResource unless explicitly necessary.
java 代码里读取jar包下resources目录下的文件
在进行Java项目开发时,资源文件的读取是一个常见的需求,尤其是当这些文件被放置在resources目录下。然而,有时在将项目打包至Linux环境或部署到Tomcat服务器后,可能会遇到文件找不到的问题。本文将介绍几种在Java代码中读取resources目录下文件的方法,并通过实际操作来解答如何确保资源文件在各种环境中都能被成功访问。源码分析经验
在开始实践前,我们首先明确几个关键点:
1. **java.io.File** 类:在IDEA开发环境中使用此方法时,文件路径的构建可能会出现问题,因此不推荐直接使用此方法进行资源文件读取。
2. **java.lang.ClassLoader#getSystemResourceAsStream**:此方法提供了从系统类加载器中获取资源文件的流,但在某些情况下,可能无法直接适用于项目中的资源文件读取。
3. **class.getClassLoader().getResourceAsStream**:通过当前类的类加载器获取资源文件流,这是一种通用且推荐的方法,适用于各种情况。
4. **org.springframework.core.io.FileSystemResource**:Spring框架提供的类,用于封装文件路径和资源读取,通常与Spring应用集成时使用。
5. **org.springframework.core.io.FileSystemResourceLoader**:同样来自Spring框架,用于加载文件系统中的资源,与Spring应用集成时可能更方便。
综合考虑以上方法,推荐使用**class.getClassLoader().getResourceAsStream("text.txt")**。这种方法不仅适用于直接的Java应用,也适用于集成Spring框架的项目。它能够确保在不同环境(如Linux、Tomcat服务器)下,资源文件都能被成功读取。
实践时,请确保资源文件的路径在调用方法时正确无误。例如,如果资源文件位于resources目录下,路径应为"text.txt"。通过这种方式,可以有效解决资源文件在不同环境下的访问问题,提高项目部署和运行的稳定性。
本文提供的实践方法和建议旨在帮助开发者解决在不同环境下读取Java项目中resources目录下文件的问题。若还有其他方法或有疑问,欢迎在评论区留言讨论。