java路径解析
java路径最终解决方案http://blog.csdn.net/shendl/article/details/1427475
贴出作者写的一个工具类
这个工具的思路大概就是:
如果路径中没有带有../ 即路径在classes中,那么可以直接调用下面的这行代码获取输入流
如果路径中带有../那么作者就会将这个相对路径进行解析,解析出其绝对路径URL,然后通过URL.openStream()得到这个流
1 package com.Utils; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.net.MalformedURLException; 6 import java.net.URL; 7 import java.util.Properties; 8 9 import org.apache.commons.logging.Log; 10 import org.apache.commons.logging.LogFactory; 11 12 /** 13 *@author沈东良shendl_s@hotmail.com 14 *Nov29,2006 10:34:34AM 15 *用来加载类,classpath下的资源文件,属性文件等。 16 *getExtendResource(StringrelativePath)方法,可以使用../符号来加载classpath外部的资源。 17 */ 18 public class ClassLoaderUtil { 19 private static Log log=LogFactory.getLog(ClassLoaderUtil.class); 20 /** 21 *Thread.currentThread().getContextClassLoader().getResource("") 22 */ 23 24 /** 25 *加载Java类。 使用全限定类名 26 *@paramclassName 27 *@return 28 */ 29 public static Class loadClass(String className) { 30 try { 31 return getClassLoader().loadClass(className); 32 } catch (ClassNotFoundException e) { 33 throw new RuntimeException("class not found '"+className+"'", e); 34 } 35 } 36 /** 37 *得到类加载器 38 *@return 39 */ 40 public static ClassLoader getClassLoader() { 41 42 return ClassLoaderUtil.class.getClassLoader(); 43 } 44 /** 45 *提供相对于classpath的资源路径,返回文件的输入流 46 *@paramrelativePath必须传递资源的相对路径。是相对于classpath的路径。如果需要查找classpath外部的资源,需要使用../来查找 47 *@return 文件输入流 48 *@throwsIOException 49 *@throwsMalformedURLException 50 */ 51 public static InputStream getStream(String relativePath) throws MalformedURLException, IOException { 52 if(!relativePath.contains("../")){ 53 return getClassLoader().getResourceAsStream(relativePath); 54 55 }else{ 56 return ClassLoaderUtil.getStreamByExtendResource(relativePath); 57 } 58 59 } 60 /** 61 * 62 *@paramurl 63 *@return 64 *@throwsIOException 65 */ 66 public static InputStream getStream(URL url) throws IOException{ 67 if(url!=null){ 68 69 return url.openStream(); 70 71 72 }else{ 73 return null; 74 } 75 } 76 /** 77 * 78 *@paramrelativePath必须传递资源的相对路径。是相对于classpath的路径。如果需要查找classpath外部的资源,需要使用../来查找 79 *@return 80 *@throwsMalformedURLException 81 *@throwsIOException 82 */ 83 public static InputStream getStreamByExtendResource(String relativePath) throws MalformedURLException, IOException{ 84 return ClassLoaderUtil.getStream(ClassLoaderUtil.getExtendResource(relativePath)); 85 86 87 } 88 89 /** 90 *提供相对于classpath的资源路径,返回属性对象,它是一个散列表 91 *@paramresource 92 *@return 93 */ 94 public static Properties getProperties(String resource) { 95 Properties properties = new Properties(); 96 try { 97 properties.load(getStream(resource)); 98 } catch (IOException e) { 99 throw new RuntimeException("couldn't load properties file '"+resource+"'", e); 100 } 101 return properties; 102 } 103 /** 104 *得到本Class所在的ClassLoader的Classpat的绝对路径。 105 *URL形式的 106 *@return 107 */ 108 public static String getAbsolutePathOfClassLoaderClassPath(){ 109 110 111 ClassLoaderUtil.log.info(ClassLoaderUtil.getClassLoader().getResource("").toString()); 112 return ClassLoaderUtil.getClassLoader().getResource("").toString(); 113 114 } 115 /** 116 * 117 *@paramrelativePath 必须传递资源的相对路径。是相对于classpath的路径。如果需要查找classpath外部的资源,需要使用../来查找 118 *@return资源的绝对URL 119 *@throwsMalformedURLException 120 */ 121 public static URL getExtendResource(String relativePath) throws MalformedURLException{ 122 123 ClassLoaderUtil.log.info("传入的相对路径:"+relativePath) ; 124 //ClassLoaderUtil.log.info(Integer.valueOf(relativePath.indexOf("../"))) ; 125 if(!relativePath.contains("../")){ 126 return ClassLoaderUtil.getResource(relativePath); 127 128 } 129 //得到类加载器的绝对路径 130 String classPathAbsolutePath=ClassLoaderUtil.getAbsolutePathOfClassLoaderClassPath(); 131 ClassLoaderUtil.log.info("classPathAbsolutePath:"+classPathAbsolutePath); 132 //如果是当前目录的路径 ./ 133 if(relativePath.substring(0, 1).equals("/")){ 134 relativePath=relativePath.substring(1); 135 System.out.println(relativePath); 136 } 137 ClassLoaderUtil.log.info(Integer.valueOf(relativePath.lastIndexOf("../"))) ; 138 139 String wildcardString=relativePath.substring(0,relativePath.lastIndexOf("../")+3); 140 //../../得到其后面的路径 141 relativePath=relativePath.substring(relativePath.lastIndexOf("../")+3); 142 int containSum=ClassLoaderUtil.containSum(wildcardString, "../"); 143 classPathAbsolutePath= ClassLoaderUtil.cutLastString(classPathAbsolutePath, "/", containSum); 144 System.out.println(classPathAbsolutePath); 145 String resourceAbsolutePath=classPathAbsolutePath+relativePath; 146 ClassLoaderUtil.log.info("绝对路径:"+resourceAbsolutePath) ; 147 URL resourceAbsoluteURL=new URL(resourceAbsolutePath); 148 return resourceAbsoluteURL; 149 } 150 /** 151 *看source里面包含多少个dest 152 *@paramsource 153 *@paramdest 154 *@return 155 */ 156 private static int containSum(String source,String dest){ 157 int containSum=0; 158 int destLength=dest.length(); 159 while(source.contains(dest)){ 160 containSum=containSum+1; 161 source=source.substring(destLength); 162 163 } 164 return containSum; 165 } 166 /** 167 * 168 *@paramsource 169 *@paramdest 170 *@paramnum 171 *@return 172 */ 173 private static String cutLastString(String source,String dest,int num){ 174 // String cutSource=null; 175 for(int i=0;i<num;i++){ 176 source=source.substring(0, source.lastIndexOf(dest, source.length()-2)+1); 177 } 178 179 return source; 180 } 181 /** 182 * 183 *@paramresource 184 *@return 185 */ 186 public static URL getResource(String resource){ 187 ClassLoaderUtil.log.info("传入的相对于classpath的路径:"+resource) ; 188 return ClassLoaderUtil.getClassLoader().getResource(resource); 189 } 190 191 192 193 194 /** 195 *@paramargs 196 *@throwsMalformedURLException 197 */ 198 public static void main(String[] args) throws MalformedURLException { 199 200 //ClassLoaderUtil.getExtendResource("../spring/dao.xml"); 201 //ClassLoaderUtil.getExtendResource("../../../src/log4j.properties"); 202 //ClassLoaderUtil.getExtendResource("log4j.properties"); 203 // System.out.println(ClassLoaderUtil.getClassLoader().getResource("log4j.properties").toString()); 204 String a="abcd/efg/hijk/lmn"; 205 System.out.println(a.lastIndexOf("/", 3)); 206 } 207 208 }
InputStream input = this.getClass().getClassLoader().getResourceAsStream("Book.xml");//得到类加载器,这个是在当前的classpath下面查找Book.xml
如果直接getResourceAsStream(filePath);这个filePath只能在classPath下面(如图的classes下面),可以用 ./com/Book.xml(等价于 com/Book.xml).
源代码对不在这个classPath下面的路径可能没有相应的解析功能,如../Book.xml就会报错
而作者写的这个工具类可以使用classPath的上层路径如../Book.xml获取build目录下面的xml
我看了下源代码,最终还是使用了URL.openStream();将这个Book.xml构造成URL的绝对路径形式来获得这个流
引用作者这句话
因此,归根结底,Java本质上只能使用绝对路径来寻找资源。所有的相对路径寻找资源的方法,都不过是一些便利方法。不过是API在底层帮助我们构建了绝对路径,从而找到资源的!
URL URI String
只能通过URL来打开资源
本地系统路径 D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b
URL file:/F:/workspace/Test/Book.xml