`

如何用Spring读取JAR中的文件

 
阅读更多
   
使用如下方式读取JAR中的文件出错

   类路径下放了一个jarfile.jar,如下所示:

   如上所示,com/yyy/1.txt放在jarfile.jar中。
   我原来使用如下的方式读取这个JAR中的文件:
@Test
public void usingSpringMethod() throws Throwable {
	PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
	Resource[] resources = patternResolver.getResources("com/yyy/1.txt");
	if (resources != null && resources.length > 0) {
		File file = resources[0].getFile();//<---①
		FileInputStream inputStream = new FileInputStream(file);
		InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
		char[] data = new char[100];
		inputStreamReader.read(data);
		assertEquals((new String(data)).trim(), "ddddd");
	}
}

   运行后,抛出异常,其问题出在①处,原因是:JAR中的文件无法以File方式返回,而只有在文件系统中的类资源才可以以File的形式返回。
   但是,不管是文件系统中的类资源,还是JAR中的类资源文件,都可以以流的形式读取,因此,如上的代码调整一下就正常了:
@Test
public void usingSpringMethod() throws Throwable {
	PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
	Resource[] resources = patternResolver.getResources("com/yyy/1.txt");//<--②
	if (resources != null && resources.length > 0) {
		InputStreamReader inputStreamReader = new InputStreamReader(resources[0].getInputStream());//<---①
		char[] data = new char[100];
		inputStreamReader.read(data);
		assertEquals((new String(data)).trim(), "ddddd");
	}
}

   上面①处,使用resource[0].getInputStream()代替原来的
引用
resources[0].getFile()
。当然,②处的资源路径表达式,可以使用Spring的其它方式表示:
   方式1:
Resource[] resources = patternResolver.getResources("classpath:com/yyy/1.txt");

   方式2:
Resource[] resources = patternResolver.getResources("classpath*:com/yyy/1.txt");


直接原生的JDK方式读取
   Spring对资源路径的表达方式非常灵活,这是我们首选使用Spring加载资源的原因。当然,使用JDK原生的ClassLoader也可以加载JAR中的资源文件,如下所示:
    
@Test
public void usingJDKMethod() throws Throwable {
	URL url = getClass().getClassLoader().getResource("com/yyy/1.txt");//<--①
	InputStreamReader inputStreamReader = new InputStreamReader(url.openStream());
	char[] data = new char[100];
	inputStreamReader.read(data);
	assertEquals((new String(data)).trim(), "ddddd");
}

    唯一的限制是,在①处不再支持classpath:或classpath*:的前缀了。
  • 大小: 11.8 KB
3
0
分享到:
评论
4 楼 youjianbo_han_87 2012-10-09  
您的Spring 3.X 这本书定价对于学生一族太贵了,
3 楼 stamen 2012-04-14  
jinnianshilongnian 写道
你没贴全内容?

这个跟jar包没关系,跟classpath有关

之前我总结过下边四种方式

1、获取本地文件系统资源(不推荐使用,最后没招时使用)
File
2、获取当前类所在目录下的资源
MyServlet.class.getResourceAsStream(name)
3、获取Classpath资源
Thread.currentThread().getContextClassLoader().getResourceAsStream(name)

getClass().getClassLoader.getResourceAsStream(name)
4、读取web上下文下资源
ServletContext.getResourceAsStream(name)

//这个只返回文件系统类路径资源,不会包含jar包路径
Enumeration<URL> urls = new MyTest().getClass().getClassLoader().getResources("");

//这个即返回文件系统类路径资源,也包含jar包路径
Enumeration<URL> urls = new MyTest().getClass().getClassLoader().getResources("META-INF/MANIFEST.MF");


   在“com.springsource.cn.sf.cglib-2.2.0.jar”里包含“asm-license.txt”文件,对于使用“classpath*: asm-*.txt”进行通配符方式加载资源将什么也加载不了“asm-license.txt”文件,注意一定是模式路径匹配才会遇到这种问题。这是由于“ClassLoader”的“getResources(String name)”方法的限制,对于name为“”的情况将只返回文件系统的类路径,不会包换jar包根路径。

@Test  
public void testClasspathAsteriskPrefixLimit() throws IOException {  
    ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();      //将首先通过ClassLoader.getResources("")加载目录,  
    //将只返回文件系统的类路径不返回jar的跟路径  
    //然后进行遍历模式匹配  
    Resource[] resources = resolver.getResources("classpath*:asm-*.txt");  
    Assert.assertTrue(resources.length == 0);  
    //将通过ClassLoader.getResources("asm-license.txt")加载  
    //asm-license.txt存在于com.springsource.net.sf.cglib-2.2.0.jar  
    resources = resolver.getResources("classpath*:asm-license.txt");  
    Assert.assertTrue(resources.length > 0);       
    //将只加载文件系统类路径匹配的Resource  
    resources = resolver.getResources("classpath*:LICENS*");  
    Assert.assertTrue(resources.length == 1);  
}  


对于“resolver.getResources("classpath*:asm-*.txt");”,由于在项目“resources”目录下没有所以应该返回0个资源;“resolver.getResources("classpath*:asm-license.txt");”将返回jar包里的Resource;“resolver.getResources("classpath*:LICENS*");”,因为将只返回文件系统类路径资源,所以返回1个资源。

因此在通过前缀“classpath*”加载通配符路径时,必须包含一个根目录才能保证加载的资源是所有的,而不是部分。

http://jinnianshilongnian.iteye.com/blog/1416322

   分析得非常好,特别是对直接放在根路径下的文件的分析,这是很容易出错的地方。
2 楼 stamen 2012-04-14  
呵呵,真是没有写全,今天补上了。
1 楼 jinnianshilongnian 2012-04-13  
你没贴全内容?

这个跟jar包没关系,跟classpath有关

之前我总结过下边四种方式

1、获取本地文件系统资源(不推荐使用,最后没招时使用)
File
2、获取当前类所在目录下的资源
MyServlet.class.getResourceAsStream(name)
3、获取Classpath资源
Thread.currentThread().getContextClassLoader().getResourceAsStream(name)

getClass().getClassLoader.getResourceAsStream(name)
4、读取web上下文下资源
ServletContext.getResourceAsStream(name)

//这个只返回文件系统类路径资源,不会包含jar包路径
Enumeration<URL> urls = new MyTest().getClass().getClassLoader().getResources("");

//这个即返回文件系统类路径资源,也包含jar包路径
Enumeration<URL> urls = new MyTest().getClass().getClassLoader().getResources("META-INF/MANIFEST.MF");


   在“com.springsource.cn.sf.cglib-2.2.0.jar”里包含“asm-license.txt”文件,对于使用“classpath*: asm-*.txt”进行通配符方式加载资源将什么也加载不了“asm-license.txt”文件,注意一定是模式路径匹配才会遇到这种问题。这是由于“ClassLoader”的“getResources(String name)”方法的限制,对于name为“”的情况将只返回文件系统的类路径,不会包换jar包根路径。

@Test  
public void testClasspathAsteriskPrefixLimit() throws IOException {  
    ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();      //将首先通过ClassLoader.getResources("")加载目录,  
    //将只返回文件系统的类路径不返回jar的跟路径  
    //然后进行遍历模式匹配  
    Resource[] resources = resolver.getResources("classpath*:asm-*.txt");  
    Assert.assertTrue(resources.length == 0);  
    //将通过ClassLoader.getResources("asm-license.txt")加载  
    //asm-license.txt存在于com.springsource.net.sf.cglib-2.2.0.jar  
    resources = resolver.getResources("classpath*:asm-license.txt");  
    Assert.assertTrue(resources.length > 0);       
    //将只加载文件系统类路径匹配的Resource  
    resources = resolver.getResources("classpath*:LICENS*");  
    Assert.assertTrue(resources.length == 1);  
}  


对于“resolver.getResources("classpath*:asm-*.txt");”,由于在项目“resources”目录下没有所以应该返回0个资源;“resolver.getResources("classpath*:asm-license.txt");”将返回jar包里的Resource;“resolver.getResources("classpath*:LICENS*");”,因为将只返回文件系统类路径资源,所以返回1个资源。

因此在通过前缀“classpath*”加载通配符路径时,必须包含一个根目录才能保证加载的资源是所有的,而不是部分。

http://jinnianshilongnian.iteye.com/blog/1416322

相关推荐

    spring读取jar中的配置文件

    总结起来,Spring提供了多种方式读取JAR内配置文件,包括`@PropertySource`、`@ConfigurationProperties`以及直接使用`Resource`接口。理解这些方法的使用和它们之间的差异对于开发和维护复杂的Spring应用至关重要。...

    spring读取配置文件

    本篇文章将深入探讨如何在Spring中读取不同目录下的配置文件,以及使用`ClassPathXmlApplicationContext`和`FileSystemXmlApplicationContext`这两种不同的上下文环境来加载它们。 首先,让我们了解`...

    读取war包或jar包内的文件

    - `TestWarAndJar1.java`可能包含了一个简单的示例,演示如何使用`getResourceAsStream()`直接读取JAR或WAR内的文本文件。 - `TestWarAndJar2.java`可能进一步扩展,展示如何处理其他类型的资源,比如图片或XML...

    spring开发jar包

    使用Maven下载Spring的jar包,只需要在pom.xml文件中添加对应的依赖,Maven会自动解决依赖关系并下载到本地仓库。这种方式比直接下载jar包更加方便和高效,因为Maven可以处理版本冲突和依赖管理问题。 总的来说,...

    springjar架包文件

    Spring框架是Java开发中不可或缺的一部分,它以其模块化、易用性和灵活性著称。这个"springjar架包文件"显然包含了一系列与Spring框架...为了使用这些JAR文件,需要在项目的类路径中包含它们,并正确配置Spring容器。

    如何加载jar包中的spring配置文件

    在Spring MVC项目中,加载jar包中的Spring配置文件是一个常见的需求,特别是在进行SSM(Spring、Spring MVC、MyBatis)整合时。SSM框架的整合通常涉及到多个配置文件的组织和管理,其中一部分配置可能会被打包到独立...

    Spring 基础jar包

    在压缩包中,`readme.txt`通常包含有关如何使用这些jar包的说明,而`spring 基础包`可能包含了Spring框架的基础组件,如`spring-core.jar`、`spring-context.jar`等,它们提供了上述功能的基础实现。使用这些jar包,...

    spring-lib Spring 核心jar包

    Spring框架是Java开发中不可或缺的一部分,它以其模块化、易扩展和高度可配置性而闻名。这个名为"spring-lib"的压缩包包含了Spring的核心jar包,这些库是构建基于Spring的应用程序的基础。让我们深入探讨一下Spring...

    Spring3.0jar包

    使用时,开发者可以根据项目需求选择导入相应的jar包,例如,如果仅使用Spring的DI功能,那么可以导入core-container相关的jar;如果涉及到Web开发,就需要添加spring-web和spring-webmvc的jar包。 在实际开发中,...

    spring的jar包

    这个名为"spring的jar包"的压缩文件很可能是包含了Spring框架的核心组件和其他相关模块。 Spring框架的核心特性包括: 1. **依赖注入(Dependency Injection, DI)**:Spring通过DI来管理对象的生命周期和对象之间的...

    解决SpringBoot jar包中的文件读取问题实现

    通过`Class`对象的`getResourceAsStream()`方法,我们可以获取到一个输入流,从而读取jar内的资源,如下所示: ```java public static void main(String[] args) throws IOException { InputStream inputStream = ...

    jsf+spring的jar包

    在Spring中,Digester可以用来读取配置文件,自动创建和配置bean。`commons-logging.jar`是Apache Commons Logging库,它提供了一个统一的日志接口,允许开发者选择不同的日志实现,如log4j或java.util.logging。 `...

    Spring文件上传和下载所需的jar包.rar

    为了在Spring项目中使用这些库,你需要将Apache Commons IO的`commons-io-2.6.jar`和Apache Commons FileUpload的`commons-fileupload-1.3.3.jar`添加到项目的类路径中。如果是Maven项目,可以在pom.xml文件中添加...

    mybatis-spring.jar整合包(包含两个版本,有源码jar包)

    MyBatis-Spring整合包是将流行的ORM框架MyBatis与Spring框架紧密集成的一个库,旨在简化在Spring应用中使用MyBatis的过程。这个整合包提供了便捷的数据访问接口和事务管理,使得开发者能够更容易地在Spring应用中...

    spring.jar包

    9. **Spring Boot**:虽然不是`spring.jar`包的一部分,但Spring Boot是基于Spring框架的快速开发工具,简化了Spring应用的初始化和配置过程,是现代Spring项目中常见的选择。 10. **Web服务支持**:Spring还提供了...

    spring操作的基本jar包

    4. **dom4j-1.6.1.jar**:这是一个用于XML处理的库,Spring框架在读取和解析XML配置文件时会用到。它提供了强大的文档对象模型API,使得处理XML文件变得简单。 5. **spring-expression-4.2.3.RELEASE.jar**:Spring...

    spring4.1.1相关jar包

    4. **spring-beans-4.1.1.RELEASE.jar**:处理Spring Bean的定义和实例化,包括从XML或Java配置中读取bean定义,并负责bean之间的依赖注入。 5. **spring-web-4.1.1.RELEASE.jar**:提供HTTP相关功能,如Servlet ...

    CXF和spring整合所需jar包

    3. **cxf-rt-wsdl.jar**:WSDL(Web Service Description Language)解析库,用于读取和处理WSDL文件,以便生成服务端点和服务客户端代理。 4. **cxf-rt-bindings-soap.jar**:提供SOAP绑定支持,使得CXF能够将SOAP...

    spring-framework-4.3.5 所有JAR文件包

    这些JAR文件包括了Spring的核心模块、Web模块、数据访问模块以及测试模块等,确保了开发过程的高效性和灵活性。通过理解并掌握这些知识点,开发者可以充分利用Spring Framework 4.3.5的强大功能来创建高质量的应用...

    Spring用的两个jar

    在给定的压缩包文件中,我们有两个关键的JAR文件:`commons-logging-1.0.4.jar`和`spring.jar`,它们都是Spring框架的核心组件。 首先,`commons-logging-1.0.4.jar`是Apache Commons Logging库的一个版本。这个库...

Global site tag (gtag.js) - Google Analytics