`
dylan0514sina.cn
  • 浏览: 94934 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JAVA中查找类或资源文件

    博客分类:
  • any
 
阅读更多

   根据语义的不同,查找类或资源的方式通常不太一样;Servlet语义下查找的类或资源必须在WEB根目录下;在URLClassloader语义下查找的类或资源在指定的URL中;
而java.io.File查找的类或资源特定于本地文件系统,File实例文件和目录路径名的抽象表示形式,并不能说明文件系统就存在对应的目录或文件,可以用exist方法断定文件是否存在;构造File实例的时候,需要传入代表路径的字符串,正如getPath的含义一样只是返回这个字符串本身;如果字符串表达的是相对路径,则使用它和文件系统交互之前,必须加入前缀,这里指工作目录由System.getProperty("user.dir")确定,由前缀和传入字符串共同确定文件的唯一性,还有一点工作要做。拼接上之后构成了能够表达绝对路径的字符串,虽然能够表达“绝对路径”的意思,不见得特定操作系统接受它,比如多了"..",有些操作系统可能自身内部处理这些细节,但是在相互之前,这种责任应该由请求者JVM担当,对于JVM来说必须将路径规范化,才能和操作系统交互
  getPath 返回构造File实例的传入字符串
  getAbsolutePath 返回绝对路径:去除传入字符串的不必要的“/”或文件分隔符
  getCanonicalPath 返回绝对路径:去除传入字符串的不必要的“、”或文件分隔符;同时去除多余的“.”或“..”;改返回值是文件系统的唯一标准表示
  如果传入path是相对的,则用System.getProperty("user.dir")合并得到完整路径
注意:File实例代表的是本地系统文件,如果文件存在,可以用FileOutputStream或FileInputStream流操作本地文件;但针对压缩文件内的文件,File实例的很多操作不能正确进行,必须使用java.util.zip压缩API操作,如果读取压缩文件中的文件(在Java中,称这些内置文件为“条目”即目录、文件),需进行解压之后判断。
  在web应用中,我们经常直接或间接用ServletContext来定位资源,servlet语义下,定位资源必须在webroot之下。 
getResourcePaths 传入的路径必须以"/"开始,返回相对于web root 或/WEB-INF/lib/xxx.jar/META-INF/resources
所有下级目录或文件:
For example, for a web application containing:
   /welcome.html
   /catalog/index.html
   /catalog/products.html
   /catalog/offers/books.html
   /catalog/offers/music.html
   /customer/login.jsp
   /WEB-INF/web.xml
   /WEB-INF/classes/com.acme.OrderServlet.class
   /WEB-INF/lib/catalog.jar!/META-INF/resources/catalog/moreOffers/books.html

getResourcePaths("/") would return {"/welcome.html", "/catalog/", "/customer/", "/WEB-INF/"}, and

getResourcePaths("/catalog/") would return {"/catalog/index.html", "/catalog/products.html", "/catalog/offers/", "/catalog/moreOffers/"}.

  getResource 返回路径的单个URL,查找方式同上,先查找web root,找不到再查找/WEB-INF/lib/xxx.jar/META-INF/resource
  getResourceAsStream 实现代理到getResource,然后返回url.openStream

  基于java.lang.Class实例的资源查找
  getResource 返回单个URL。如果name以"/"开头,则代理给Classloader的是"/"之后的部分;否则代理的是当前Class的包名(以"/"代替".")+name
  getResourceAsStream 代理url.openStream

  基于ClassLoader资源查找 
  Classloader有父子关系,getResource或getResources使用委托机制由父Classloader查找,如果找不到调用findResource(s)。
  getResource 查找具有给定名称的资源返回单个URL
  getResources 查找所有给定名称的资源返回URL列表
  getResourceAsStream 代理url.openStream,返回读取指定资源的输入流
  findResources 由子类实现
  getSystemResource和getSystemResourceAsStream为静态方法,由系统类加载器加载。

  使用ClassLoader加载类之前必须定位类文件,跟定位资源文件如图片一样。这个定位如果使用java.io.File表达,也就是说特定于本地系统文件;而嵌套的Applet下载的class执行文件可以处于网络的任何位置,只要能够下载;无论怎么样,仅仅使用File实例,对于ClassLoader的实现来讲是不够的,必须支持各式各样的路径表示。URL”人如其名"
”统一资源定位“,JVM将使用java.net.URL表达资源路径而使用URLClassLoader进行类或资源查找。
  JVM使用委托机制查找类或资源文件,其中很有名气的是AppClassLoader和ExtClassLoader,他们都支持URL资源。比如 AppClassLoader指定java.class.path下的所有文件转换为URL;例如
D:\developTools\workspace\ims\build\classes;D:\developTools\workspace\ims\lib\extreme\extremecomponents-1.0.4.jar;将转换成
URL url1 = new URL("file","","D:\developTools\workspace\ims\build\classes");
URL url2 = new URL(("file","D:\developTools\workspace\ims\lib\extreme\extremecomponents-1.0.4.jar",");
URL[] urls = new URL[]{url1,url2};
ExtClassLoader指定java.ext.dirs下的所有文件,处理方式和AppClassLoader一样,最终这些URL将被存储在URL数组中以供sun.misc.URLclasspath使用。

  每个URLClassLoader提供相应的URL给URLclasspath中,当URLClassLoader的资源查找由URLclasspath统一处理,终究落实到URLclasspath的getResource(s)、findResource方法。资源查找方法依次在每个URL中查找资源,针对URL特殊性。
  URL以“/”结尾的,认为是一个目录:
    如果URL指定资源位于本地系统,则使用java.io.File实例如new File(url,resource),通过确定存在性返回resource的URL。
    否则使用URL实例如new URL(url,resource),通过url.connect确定存在性返回resourceURL,同时如果此URL是一个jar URL,必须使用正确的jar URL格式 jar:*****.jar!/xxxx
  否则认为是一个Jar文件,则使用专门的JarLoader加载器进行加载,这种JarLoader充分利用 ”索引“加速加载

  JAR索引
   如果一个应用程序或者 applet 捆绑到多个 JAR 文件中,那么类装载器就使用一个简单的线性搜索算法搜索类路径中的每一个元素,这使类装载器可能要下载并打开许多个 JAR 文件,直到找到所要的类或者资源。如果类装载器试图寻找一个不存在的资源,那么在应用程序或者 applet 中的所有 JAR 文件都会下载。对于大型的网络应用程序和 applet,这会导致启动缓慢、响应迟缓并浪费带宽。
从 JDK 1.3 以后,JAR 文件格式开始支持索引以优化网络应用程序中类的搜索过程,特别是 applet。JarIndex 机制收集在 applet 或者应用程序中定义的所有 JAR 文件的内容,并将这些信息存储到第一个 JAR 文件中的索引文件中。下载了第一个 JAR 文件后,applet 类装载器将使用收集的内容信息高效地装载 JAR 文件(以上“JAR索引”摘抄于http://www.ibm.com/developerworks/cn/java/j-jar/ JAR索引章节)

  JAR索引实现依赖于meta-index和index-list。 ExtClassLoader初始化时,将通过meta-index文件建立jar文件和类或资源文件之间的映射关系;按需加载类或资源的时候,
根据当前URL JAR查找这种关系,如果该JAR已经在meta-index中声明过,但文件中指定的类或资源与当前查找不匹配,则退出该JAR检索;当前JAR的JarLoader初始化时根据INDEX.LIST建立映射关系,拥有这种文件的JAR属于“主”JAR,文件中描述的其他JAR相对“主”JAR来说,是“副”JAR,当“主”JAR中查找不到对应资源的时候会依次查找"副"JAR,同时如果”副“JAR中也有INDEX.LIST文件,则根据当前文件建立和其他JAR的”主 副“关系,再找到资源之前,这种关系会根据INDEX.LIST递归建立。与当JAR中含有INDEX.LIST文件而meta-index却没指定META-INF/INDEX.LIST,这种情况下的INDEX.LIST视为无效。

  meta-index
  ExtClassLoader比AppClassLoader多做了一件事,java.ext.dirs指定的扩展目录截图

  可以清楚看到有个meta-index文件,这个文件内容如下:

% VERSION 2
% WARNING: this file is auto-generated; do not edit
% UNSUPPORTED: this file and its format may change and/or
%   may be removed in a future release
# dnsns.jar
META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor
sun/net
# localedata.jar
sun/text
sun/util
# sunjce_provider.jar
com/sun/crypto/
META-INF/JCE_RSA.RSA
META-INF/JCE_RSA.SF
# sunmscapi.jar
sun/security
META-INF/JCE_RSA.RSA
META-INF/JCE_RSA.SF
# sunpkcs11.jar
sun/security
META-INF/JCE_RSA.RSA
META-INF/JCE_RSA.SF


编写一个meta-index文件注意
  •   首行必须以% VERSION 2 开始,
  •   引用的jar包相对于meta-index所在目录
  •   引用Jar的行必须以# ! @,后加一个”空格“
  •   以! 开头的jar接下来的几行指定的文件必须是class文件

这些引用的JAR包将会被添加到ExtClassloader url数组中,同时根据meta-index内容为这些JAR包建立”索引“,当加载这些JAR URL时,如果对应的“索引”存在但指定的资源不包括,则认为是“没找到”,返回NULL;

创建一个 JarIndex
可以通过在 jar命令中指定 -i选项创建一个 JarIndex。命令行中第一个JAR是”主“。


”主“JAR中新增了一个INDEX.LIST文件
JarIndex-Version: 1.0

dnsns.jar
sun
sun/net
sun/net/spi
sun/net/spi/nameservice
sun/net/spi/nameservice/dns
META-INF/services

sunjce_provider.jar
META-INF
com
com/sun
com/sun/crypto
com/sun/crypto/provider

sunpkcs11.jar
META-INF
sun/security/pkcs11
sun/security/pkcs11/wrapper

sunmscapi.jar
META-INF
sun
sun/security
sun/security/mscapi

localedata.jar
sun
sun/text
sun/text/resources
sun/util
sun/util/resources


  JarLoader加载器将充分利用Jar索引机制,如果指定的URL以”/“结尾将使用之前讨论过的Loader机制,这时Jar索引机制是无效的,所以开发中避免写URL时,不要画蛇添足多加"/"例如xxxx.jar/。同时如果找不到meta-index和index.list映射关系,那么JarLoader将jar文件的manifest.mf中指定的Class-Path URL路径添加到搜索路径中。
特殊情况:当args为空或"."时将找不到对应的条目,返回NULL


Spring中提供的资源访问API。

public interface Resource extends InputStreamSource {

    boolean exists();

    boolean isOpen();

    URL getURL() throws IOException;

    File getFile() throws IOException;

    Resource createRelative(String relativePath) throws IOException;

    String getFilename();

    String getDescription();
}

ClassPathResource,UrlResource,FileSystemResource,ServletContextResource等都实现了。ResourceLoader接口将根据如下情况返回单个资源实例
public interface ResourceLoader {
    Resource getResource(String location);
}

public interface ResourcePatternResolver extends ResourceLoader{
    String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
    Resource[] getResources(String locationPattern) throws IOException;
}
  Spring提供了该接口的默认实现DefaultResourceLoader:
location以“classpath:”开始,则使用ClassPathResource或其子实例
location是一个标准的URL,则使用UrlResource,不支持JAR路径
否则根据ApplicationContext(ResourceLoader子类)具体实现返回不同实例
ClassPathXmlApplicationContext 返回ClassPathResource或其子实例
FileSystemXmlApplicationContext 返回FileSystemResource
WebApplicationContext 返回ServletContextResource

  也提供了ANT风格通配符支持比如classpath*:META-INF/*-context.xml,由PathMatchingResourcePatternResolver实现:
  1.有"classpath*:”,含ANT通配符则返回所有匹配资源
  2.有"classpath*:”,不含ANT通配符则代理classloader.getResources返回多个资源
  3.无"classpath*:”,含ANT通配符则返回所有匹配资源
  4.无"classpath*:",不含ANT通配符则代理DefaultResourceLoader.getResource返回单个资源





  • 大小: 41.5 KB
  • 大小: 3.5 KB
  • 大小: 11.1 KB
  • 大小: 105.2 KB
  • 大小: 78.5 KB
0
4
分享到:
评论

相关推荐

    java 静态代码块通过类加载器获取资源文件例子

    这两个方法可以从类路径中查找指定的资源文件,并返回一个URL对象或输入流,便于我们进一步处理。例如,获取名为"config.properties"的属性文件,我们可以这样编写代码: ```java InputStream inputStream = ...

    java重复文件查找

    在Java编程领域,重复文件查找是一项常见的需求,尤其是在大型项目或者资源管理中。这个程序能够帮助用户在指定的目录下高效地找出所有重复的.java和.class文件,这对于我们理解和优化项目结构、节省存储空间至关...

    Java简易文件管理器

    3.实现文本类文件(.txt, .java, .ini, .bat, )的预览功能(比如实现对前100行文本在某个小窗口中进行预览)。4.实现文件的重命名功能。5.实现对某个文件夹进行统计功能(如统计文件夹中文件数目)。

    java读取项目中的文件(src目录下)

    - 通常,Java项目有一个标准的目录结构,如`src/main/java`用于存放Java源代码,`src/main/resources`用于存放资源文件,如配置文件、图片或文本文件等。如果你的文件直接放在`src`目录下,可能意味着它是在源代码...

    Java实现从jar包中读取指定文件的方法

    在Java编程中,有时我们需要从已经打包的JAR文件中读取特定的资源文件,例如配置文件、图片或库。本篇文章将详细讲解如何在Java中实现从JAR包中读取指定文件的方法。 首先,Java提供了`java.util.jar`包,其中包含...

    java读取资源文件

    这个例子展示了如何在IDEA中通过`getResourceAsStream()`方法读取并处理资源文件中的图片。 总之,Java提供了多种方式来读取项目中的资源文件,通过理解类路径和使用适当的IO方法,可以有效地在IDEA环境中加载和...

    在系统中文件查找java代码

    在大量文件中查找特定内容时,简单的遍历可能效率低下。这时可以使用更高级的数据结构和算法,如Trie树或二分查找等。例如,如果我们需要在一个目录结构中搜索包含特定关键词的文件,可以构建一个文件索引,然后对...

    java文件路径获取

    - **Classpath**: 是Java运行环境的一个重要概念,它指定了Java虚拟机(JVM)加载类和资源文件的路径。 - **Resource**: 在Java中通常指的是类路径下的文件,如配置文件、图片等非可执行代码的文件。 - **URL**: ...

    java串口资源文件

    然后,将RXTX的jar文件(通常命名为rxtxSerial.jar和rxtxParallel.jar)复制到JRE的lib目录下,这是Java类加载器查找依赖库的地方。 在具体编程时,你可以使用RXTX提供的SerialPort类来创建和配置串口对象,设置...

    java实现windows文件系统操作监控

    5. **文件检索**:文件检索可能涉及到遍历目录结构,查找特定类型的文件或满足特定条件的文件。Java的`java.io.File`类提供了便利的方法,如`listFiles()`和`exists()`,用于实现这个功能。 6. **文件保护**:为了...

    java 查找主机的资源

    综上所述,Java查找主机的资源主要通过`java.net`包中的类,如InetAddress、Socket、ServerSocket和URL等,实现网络连接、IP查找、数据传输等功能。理解并熟练运用这些工具,能帮助开发者构建功能丰富的网络应用。...

    Java语言对properties资源文件的处理

    - **ResourceBundle**类专为国际化设计,它可以自动查找与当前区域设置匹配的资源文件,从而实现应用的多语言支持。此外,`ResourceBundle`可以处理不仅仅是properties文件,还可以是其他类型的资源,如图像或音频...

    java 文件查看器

    JAR是Java平台的标准归档格式,用于将多个Java类文件、资源文件和元数据打包到一个单一的文件中。这有助于减少网络传输的时间,同时还可以实现版本控制和安全特性,如数字签名。 2. **查看JAR包内容**: 通常,...

    java文件的加载

    - 该目录通常用于存放Java类文件、属性文件以及其他需要被包含在Web应用中的资源文件。 - 在Spring等Web框架中,这是一个重要的位置,用于存放配置文件等。 2. **src/main/resources** - 开发阶段,资源文件通常...

    java 只显示文件中指定的字符

    在Java编程语言中,有时我们需要从文本文件中提取或显示特定的字符,这可能是为了数据分析、日志处理或者任何其他需要筛选信息的场景。本文将详细介绍如何使用Java来实现只显示文件中指定的字符。 首先,我们需要...

    JAVA文件学习,文件搜索器

    6. **性能优化**:在大量文件中搜索可能需要考虑缓存、索引或预加载策略以提高效率。 7. **异常处理**:文件操作中可能出现各种异常,如文件不存在、权限问题等,良好的异常处理机制可以确保程序的健壮性。 通过...

    java操作本地文件

    Java 操作本地文件是软件开发中的基础操作,尤其在服务器端编程中不可或缺。Java 的 I/O(输入/输出)库提供了丰富的类和方法,使得我们可以方便地进行文件的创建、读取、写入、删除、重命名等操作。在本教程中,...

    java 操作xml文件(包含xml文件和对应jar包)

    我们可能需要读取XML文件中的数据,例如,使用DOM API的`DocumentBuilderFactory`和`DocumentBuilder`来创建`Document`对象,然后通过`getElementsByTagName`、`getElementsByTagnameNS`等方法查找元素,再用`...

    从java jar文件包中读资源的常用方法

    JAR(Java Archive)文件是一种用于打包Java类库和资源文件的格式,它类似于ZIP文件,但同时支持元数据和类路径信息。在Java应用程序中,JAR文件可以作为独立的可执行程序或作为库被其他项目引用。JAR文件中的资源...

Global site tag (gtag.js) - Google Analytics