最近遇到一些Jar包内外配置文件读取的问题。索性自己测试总结一下,与大家分享。

  • 绝对路径文件读取,最简单,最直接的方式

 

 
   
  1. /** 
  2.  * 从绝对路径读取文件,最基本的文件读取方式 
  3.  *  
  4.  * @author lihzh 
  5.  * @data 2012-4-11 下午9:33:44 
  6.  */ 
  7. @Test 
  8. public void testGetFileFromAbsolutePath() { 
  9.     String dirPathNotUnderClasspath = "D:\\workspace-home\\JavaDemo\\conf"
  10.     File dirFile = new File(dirPathNotUnderClasspath); 
  11.     AssertDirFile(dirFile); 
  12.  
  13.        /** 
  14.  * 对文件夹类型文件的断言 
  15.  *  
  16.  * @param dirFile 
  17.  * @author lihzh 
  18.  * @data 2012-4-11 下午9:49:14 
  19.  */ 
  20. private void AssertDirFile(File dirFile) { 
  21.     // 文件存在 
  22.     Assert.assertTrue(dirFile.exists()); 
  23.     // 是绝对路径 
  24.     Assert.assertTrue(dirFile.isAbsolute()); 
  25.     // 是个文件夹 
  26.     Assert.assertTrue(dirFile.isDirectory()); 
  27.     // 获取文件夹下所有文件 
  28.     File[] files = dirFile.listFiles(); 
  29.     // 下面有文件 
  30.     Assert.assertNotNull(files); 
  31.     // 且只有一个 
  32.     Assert.assertEquals(1, files.length); 
  33.     // 文件名匹配 
  34.     Assert.assertEquals("test.properties", files[0].getName()); 

 

  •  相对于执行编译命令路径的方式读取

 

 
    
  1. /** 
  2.  * 从相对路径读取文件,相对于编译路径,在Eclipse中即为工程所在根目录。 本质还是绝          * 对路径读取。 
  3.  *  
  4.  * @author lihzh 
  5.  * @data 2012-4-11 下午9:51:10 
  6.  */ 
  7. @Test 
  8. public void testGetFileFromRelativePath() { 
  9.     String dirPath = System.getProperty("user.dir") + "\\conf"
  10.     File dirFile = new File(dirPath); 
  11.     AssertDirFile(dirFile); 

 

  • 用URI构造本地文件读取

 

 
    
  1.  /** 
  2.  * 构造URI/URL格式的文件路径,读取本地文件 
  3.  *  
  4.  * @author lihzh 
  5.  * @throws URISyntaxException 
  6.  * @throws MalformedURLException 
  7.  * @data 2012-4-11 下午10:25:00 
  8.  */ 
  9. @Test 
  10. public void testGetFileFromURIPath() throws URISyntaxException, 
  11.         MalformedURLException { 
  12.     // 直接用URI构造, 由于URI和URL可以互转,所以如果为URL直接用URL.toURI转换成URI即可 
  13.     URI uri = new URI("file:/D:/workspace-home/JavaDemo/conf/"); 
  14.     File dirFile = new File(uri); 
  15.     AssertDirFile(dirFile); 
特别说明:用URI/URL的方式构造路径是个人比较推荐的,可以解决一些路径读取的问题。例如:Spring会对URI/URL格式的路径进行专有处理可以准确定位的位置,而直接使用绝对路径,在用Classpath和FileSystem两种不同的初始化方式下,可能会出现错误。

 


 

  • 利用ClassLoader读取Jar包内部文件

 

 
    
  1. /** 
  2.  * 从依赖的Jar包中读取文件, Jar包内的文件是无法用File读取的,只能用Stream的方式读取。 
  3.  *  
  4.  * @author lihzh 
  5.  * @throws URISyntaxException 
  6.  * @throws IOException 
  7.  * @data 2012-4-11 下午11:07:58 
  8.  */ 
  9. @Test 
  10. public void testGetFileFromJarInClassPath() throws URISyntaxException, 
  11.         IOException { 
  12.     Enumeration<URL> urls = this.getClass().getClassLoader().getResources("conf/test.properties"); 
  13.     URL url = this.getClass().getClassLoader().getResource("conf/test.properties"); 
  14.     Assert.assertTrue(urls.hasMoreElements()); 
  15.     Assert.assertNotNull(url); 
  16.     // 注意两种不同调用方式的路径的区别,此处如果不以“/” 开头,会被当作相对于当前类所在的包类处理,自然无法找到。 
  17.     // 因为在Class的getResource方法的开头,有一个resolveName方法,处理了传入的路径格式问题。而ClassLoader类里的 
  18.     // getResource和getResources均无此处理。使用时候需要用心。 
  19.     URL clzURL = this.getClass().getResource("/conf/test.properties"); 
  20.     URL nullURL = this.getClass().getResource("conf/test.properties"); 
  21.     Assert.assertNotNull(clzURL); 
  22.     Assert.assertNull(nullURL); 
  23.     URL thisClzURL = this.getClass().getResource(""); 
  24.     Assert.assertNotNull(thisClzURL); 
  25.     // 开始读取文件内容 
  26.     InputStream is = this.getClass().getResourceAsStream("/conf/test.properties"); 
  27.     Properties props = new Properties(); 
  28.     props.load(is); 
  29.     Assert.assertTrue(props.containsKey("test.key")); 
  30.     Assert.assertEquals("thisIsValue", props.getProperty("test.key")); 

 


 

  • 读取Jar内某路径下的所有文件

 

 
    
  1. /** 
  2.  * 从ClassPath中的Jar包读取某文件夹下的所有文件 
  3.  *  
  4.  * @author lihzh 
  5.  * @throws IOException  
  6.  * @data 2012-4-13 下午10:22:24 
  7.  */ 
  8. @Test 
  9. public void testGetFilesFromJarInClassPathWithDirPath() throws IOException { 
  10.     String dirPath = "conf/"
  11.     URL url = this.getClass().getClassLoader().getResource(dirPath); 
  12.     Assert.assertNotNull(url); 
  13.     String urlStr = url.toString(); 
  14.     // 找到!/ 截断之前的字符串 
  15.     String jarPath = urlStr.substring(0, urlStr.indexOf("!/") + 2); 
  16.     URL jarURL = new URL(jarPath); 
  17.     JarURLConnection jarCon = (JarURLConnection) jarURL.openConnection(); 
  18.     JarFile jarFile = jarCon.getJarFile(); 
  19.     Enumeration<JarEntry> jarEntrys = jarFile.entries(); 
  20.     Assert.assertTrue(jarEntrys.hasMoreElements()); 
  21.     Properties props = new Properties(); 
  22.     while (jarEntrys.hasMoreElements()) { 
  23.         JarEntry entry = jarEntrys.nextElement(); 
  24.         // 简单的判断路径,如果想做到想Spring,Ant-Style格式的路径匹配需要用到正则。 
  25.         String name = entry.getName(); 
  26.         if (name.startsWith(dirPath) && !entry.isDirectory()) { 
  27.             // 开始读取文件内容 
  28.             InputStream is = this.getClass().getClassLoader().getResourceAsStream(name); 
  29.             Assert.assertNotNull(is); 
  30.             props.load(is); 
  31.         } 
  32.     } 
  33.     Assert.assertTrue(props.containsKey("test.key")); 
  34.     Assert.assertEquals("thisIsValue", props.getProperty("test.key")); 
  35.     Assert.assertTrue(props.containsKey("test.key.two")); 
  36.     Assert.assertEquals("thisIsAnotherValue", props.getProperty("test.key.two")); 

 


对于不在ClassPath下的Jar包的读取,当作一个本地文件用JarFile读取即可。路径可使用绝对路径。或者用上面的url.getConnection也可以处理。这里不再实现。

PS:附件是测试用的jar包。