今天写代码的时候发现一个有趣的问题,就是在代码中读取一些资源文件(txt,gif等等)时候,单独运行的时候,当然没问题,但是当我们将项目打包成jar后,尽管资源文件在jar包内,但我们却怎么也访问不到它了。
代码结构如下:
-
src|---com
-
---cn
-
---ChineseUtil.java
-
src|---pinyin.txt
ChineseUtil.java
-
packagecom.cn;
-
-
importjava.io.FileInputStream;
-
importjava.io.FileNotFoundException;
-
importjava.io.IOException;
-
importjava.io.InputStream;
-
importjava.net.URL;
-
importjava.util.Properties;
-
-
publicclassChineseUtil{
-
privatePropertiesproperties;
-
-
publicChineseUtil(){
-
this.properties=loadProperties("pinyin.txt");
-
}
-
-
-
/**
-
*加载资源文件
-
*@paramfile
-
*@return
-
*/
-
privatePropertiesloadProperties(Stringfile){
-
Propertiesp=newProperties();
-
URLurl=this.getClass().getResource("/"+file);
-
System.out.println(url.getPath());//输出文件路径
-
try{
-
p.load(newFileInputStream(url.getFile()));
-
}catch(FileNotFoundExceptione){
-
e.printStackTrace();
-
}catch(IOExceptione){
-
e.printStackTrace();
-
}
-
returnp;
-
}
-
}
在本工程下,测试代码如下:
-
publicclassPinyinTest{
-
publicstaticvoidmain(String[]args){
-
ChineseUtilutil=newChineseUtil();
-
}
-
}
测试一切正常,没有抛出异常,但是当我们将该项目打包成jar,新建一个java工程,并仍然采用上面的java代码进行测试时,却发现代码抛出异常:
-
file:/D:/frame/pinyin.jar!/pinyin.txt
-
<spanstyle="color:#ff0000;">java.io.FileNotFoundException:file:\D:\frame\pinyin.jar!\pinyin.txt(文件名、目录名或卷标语法不正确。)</span>
抛出异常了,找不到资源文件了!让我们注意一下输出的文件的路径,file:\D:\frame\pinyin.jar!\pinyin.txt,和一般的文件路径相比,多了一个!,你不仔细观察,是看不出来的!查阅了相关资料,原来jar包中文件URL有专用格式的:jar:<url>!/{entry},而我们是不能以这种形式来new一个File的,那该怎么做呢,我们把
loadProperties方法修改如下:
-
privatePropertiesloadProperties(Stringfile){
-
Propertiesp=newProperties();
-
//注意加载资源文件的写法/表示从根目录开始否则就表示从当前类所在的路径下开始
-
InputStreamis=this.getClass().getResourceAsStream("/"+file);
-
try{
-
p.load(is);
-
}catch(FileNotFoundExceptione){
-
e.printStackTrace();
-
}catch(IOExceptione){
-
e.printStackTrace();
-
}
-
returnp;
-
}
即通过通过Class类的getResourceAsStream()方法来获取文件,这个方法是透明的,你可以像普通的File一样去定位jar包中的资源文件(不管你是jar文件还是普通的文件夹)。另外还有一个比较让人纠结的方式是使用java.util.jar.JarFile类才访问,不过使用起来非常的不习惯,具体大家可以参考API试试。
PS:接下来该看看底层是怎么实现了,有经验的朋友不妨说说
分享到:
相关推荐
Java中getResourceAsStream的用法.md
主要介绍了Java中getResourceAsStream用法,较为详细的分析了getResourceAsStream的功能及用法,需要的朋友可以参考下
主要介绍了Java 使用getClass().getResourceAsStream()方法获取资源的相关资料,这里主要讲解哪种方式可以获取到文件资源,需要的朋友可以参考下
在java类里直接读取配置文件中的信息,用到的方法是this.getClass().getClassLoader().getResourceAsStream
java项目读取配置文件的实例代码,使用class.getClassLoader().getResourceAsStream方法。
1、使用class变量的getResourceAsStream()方法 2、使用class.getClassLoader()所得到的java.lang.Clas
使用java.util.Properties类的load()方法 示例: InputStream in = lnew BufferedInputStream(new FileInputStream(name)); Properties p = new Properties(); p.load(in); 2。使用java.util....
这是基于收集的数据的 Java8 用户代理解析器实现。 为了使用这个解析器,你需要一个来自这里的解析器数据库版本: : 。 此文件不作为此存储库的一部分分发。 用法 Parser p = new Parser ( // Obtain this file ...
static是为了在静态方法中可以返回当前类中的对象 final:可加可不加,加了可以保证不可修改,且提供获取效率 3. 提供一个public修饰的方法getInstance给外部返回一个对象 4. 单例模式...
定义:可以不加声明就在JSP页面脚本(Java程序片和Java表达式)中使用的成员变量 JSP共有以下9种基本内置组件(可与ASP的6种内部组件相对应): 1.request对象 客户端的请求信息被封装在request对象中,通过它...
"操作方法:"+ "\n\n" + "游戏中用方向键和2、4、6、8键控制主角移动以及进行菜单选择,5键或OK键选定,3键调出/关闭属性菜单,左软键调出操作菜单,可查看帮助信息,保存游戏或回到主菜单。"+ "\n\n" + "关键...
如果你更愿意直接从 Java 程序而不是 XML 文件中创建 configuration,或者创建你自己的 configuration 构建器,MyBatis 也提供了完整的配置类,提供所有和 XML 文件相同功能的配置项。 ..............................
该库在内部使用Class.getResourceAsStream()方法,该方法。 该库的目标是修复这两个问题。 下载 Gradle: repositories { mavenCentral() } dependencies { implementation ' io.michaelrocks:libphonenumber-...
帮助程序可以在其他项目中使用SciView,而无需直接调用ImageJ或Scijava代码。 用法 从sc.iview.ExampleVolume RandomAccessibleInterval<UnsignedByteType> demoImg = makeDemoImg(50, 50, 50); SvFunctions.show...
InputStream is = getClass().getResourceAsStream("/db.properties"); Properties dbProps = new Properties(); try { dbProps.load(is); } catch (Exception e) { System.err.println("不能读取属性文件. ...