天天看点

随心所欲学Java,文件读取问题研究,Jar包内文件读取

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

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

/** 

 * 从绝对路径读取文件,最基本的文件读取方式 

 *  

 * @author lihzh 

 * @data 2012-4-11 下午9:33:44 

 */ 

@Test 

public void testGetFileFromAbsolutePath() { 

    String dirPathNotUnderClasspath = "D:\\workspace-home\\JavaDemo\\conf"; 

    File dirFile = new File(dirPathNotUnderClasspath); 

    AssertDirFile(dirFile); 

       /** 

 * 对文件夹类型文件的断言 

 * @param dirFile 

 * @data 2012-4-11 下午9:49:14 

private void AssertDirFile(File dirFile) { 

    // 文件存在 

    Assert.assertTrue(dirFile.exists()); 

    // 是绝对路径 

    Assert.assertTrue(dirFile.isAbsolute()); 

    // 是个文件夹 

    Assert.assertTrue(dirFile.isDirectory()); 

    // 获取文件夹下所有文件 

    File[] files = dirFile.listFiles(); 

    // 下面有文件 

    Assert.assertNotNull(files); 

    // 且只有一个 

    Assert.assertEquals(1, files.length); 

    // 文件名匹配 

    Assert.assertEquals("test.properties", files[0].getName()); 

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

 * 从相对路径读取文件,相对于编译路径,在Eclipse中即为工程所在根目录。 本质还是绝          * 对路径读取。 

 * @data 2012-4-11 下午9:51:10 

public void testGetFileFromRelativePath() { 

    String dirPath = System.getProperty("user.dir") + "\\conf"; 

    File dirFile = new File(dirPath); 

用URI构造本地文件读取

 /** 

 * 构造URI/URL格式的文件路径,读取本地文件 

 * @throws URISyntaxException 

 * @throws MalformedURLException 

 * @data 2012-4-11 下午10:25:00 

public void testGetFileFromURIPath() throws URISyntaxException, 

        MalformedURLException { 

    // 直接用URI构造, 由于URI和URL可以互转,所以如果为URL直接用URL.toURI转换成URI即可 

    URI uri = new URI("file:/D:/workspace-home/JavaDemo/conf/"); 

    File dirFile = new File(uri); 

特别说明:用URI/URL的方式构造路径是个人比较推荐的,可以解决一些路径读取的问题。例如:Spring会对URI/URL格式的路径进行专有处理可以准确定位的位置,而直接使用绝对路径,在用Classpath和FileSystem两种不同的初始化方式下,可能会出现错误。

利用ClassLoader读取Jar包内部文件

 * 从依赖的Jar包中读取文件, Jar包内的文件是无法用File读取的,只能用Stream的方式读取。 

 * @throws IOException 

 * @data 2012-4-11 下午11:07:58 

public void testGetFileFromJarInClassPath() throws URISyntaxException, 

        IOException { 

    Enumeration<URL> urls = this.getClass().getClassLoader().getResources("conf/test.properties"); 

    URL url = this.getClass().getClassLoader().getResource("conf/test.properties"); 

    Assert.assertTrue(urls.hasMoreElements()); 

    Assert.assertNotNull(url); 

    // 注意两种不同调用方式的路径的区别,此处如果不以“/” 开头,会被当作相对于当前类所在的包类处理,自然无法找到。 

    // 因为在Class的getResource方法的开头,有一个resolveName方法,处理了传入的路径格式问题。而ClassLoader类里的 

    // getResource和getResources均无此处理。使用时候需要用心。 

    URL clzURL = this.getClass().getResource("/conf/test.properties"); 

    URL nullURL = this.getClass().getResource("conf/test.properties"); 

    Assert.assertNotNull(clzURL); 

    Assert.assertNull(nullURL); 

    URL thisClzURL = this.getClass().getResource(""); 

    Assert.assertNotNull(thisClzURL); 

    // 开始读取文件内容 

    InputStream is = this.getClass().getResourceAsStream("/conf/test.properties"); 

    Properties props = new Properties(); 

    props.load(is); 

    Assert.assertTrue(props.containsKey("test.key")); 

    Assert.assertEquals("thisIsValue", props.getProperty("test.key")); 

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

 * 从ClassPath中的Jar包读取某文件夹下的所有文件 

 * @throws IOException  

 * @data 2012-4-13 下午10:22:24 

public void testGetFilesFromJarInClassPathWithDirPath() throws IOException { 

    String dirPath = "conf/"; 

    URL url = this.getClass().getClassLoader().getResource(dirPath); 

    String urlStr = url.toString(); 

    // 找到!/ 截断之前的字符串 

    String jarPath = urlStr.substring(0, urlStr.indexOf("!/") + 2); 

    URL jarURL = new URL(jarPath); 

    JarURLConnection jarCon = (JarURLConnection) jarURL.openConnection(); 

    JarFile jarFile = jarCon.getJarFile(); 

    Enumeration<JarEntry> jarEntrys = jarFile.entries(); 

    Assert.assertTrue(jarEntrys.hasMoreElements()); 

    while (jarEntrys.hasMoreElements()) { 

        JarEntry entry = jarEntrys.nextElement(); 

        // 简单的判断路径,如果想做到想Spring,Ant-Style格式的路径匹配需要用到正则。 

        String name = entry.getName(); 

        if (name.startsWith(dirPath) && !entry.isDirectory()) { 

            // 开始读取文件内容 

            InputStream is = this.getClass().getClassLoader().getResourceAsStream(name); 

            Assert.assertNotNull(is); 

            props.load(is); 

        } 

    } 

    Assert.assertTrue(props.containsKey("test.key.two")); 

    Assert.assertEquals("thisIsAnotherValue", props.getProperty("test.key.two")); 

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

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

<a href="http://down.51cto.com/data/2360293" target="_blank">附件:http://down.51cto.com/data/2360293</a>

     本文转自mushiqianmeng 51CTO博客,原文链接:http://blog.51cto.com/mushiqianmeng/833649,如需转载请自行联系原作者

继续阅读