如何读取jar包中的文件中的某个文本文件的内容

& &我们常常在代码中读取一些资源文件(比如图片,音乐,文本等等)。在单独运行的时候这些简单的处理当然不会有问题。但是,如果我们把代码打成一个jar包以后,即使将资源文件一并打包,这些东西也找不出来了。看看下面的代码:
//源代码1:
package edu.
import java.io.*;
public class Resource {
void getResource() throws IOException{
File file=new File("bin/resource/res.txt");
BufferedReader br=new BufferedReader(new FileReader(file));
String s="";
while((s=br.readLine())!=null)
System.out.println(s);
&&&这段代码写在Eclipse建立的java Project中,其目录为:(其中将资源文件res.txt放在了bin目录下,以便打成jar包)&& && 1、src/&&&&& &&& &&& src/edu/hxraid/Resource.java&& && 2、bin/&&&&& &&& &&& bin/resource/res.txt&&&&&&&&& & & bin/edu/hxraid/Resource.class
&&&&& 很显然运行源代码1是能够找到资源文件res.txt。但当我们把整个工程打成jar包以后(ResourceJar.jar),这个jar包内的目录为:&&&&& & & & & edu/hxraid/Resource.class&&&&& & & & & resource/res.txt
&&&&&&&&&而这时jar包中Resource.class字节码:ldc &String "bin/resource/res.txt"& [20] 将无法定位到jar包中的res.txt位置上。就算把bin/目录去掉:ldc &String "resource/res.txt"& [20] 仍然无法定位到jar包中res.txt上。
&&&&&&这主要是因为jar包是一个单独的文件而非文件夹,绝对不可能通过"file:/e:/.../ResourceJar.jar/resource&/res.txt"这种形式的文件URL来定位res.txt。所以即使是相对路径,也无法定位到jar文件内的txt文件(读者也许对这段原因解释有些费解,在下面我们会用一段代码运行的结果来进一步阐述)。
&&&&&&&&&&那么把资源打入jar包,无论ResourceJar.jar在系统的什么路径下,jar包中的字节码程序都可以找到该包中的资源。这会是幻想吗?
&&&&& 当然不是,我们可以用类装载器(ClassLoader)来做到这一点:
&&&&&& &&(1)&ClassLoader 是类加载器的抽象类。它可以在运行时动态的获取加载类的运行信息。&可以这样说,当我们调用ResourceJar.jar中的Resource类时,JVM加载进Resource类,并记录下Resource运行时信息(包括Resource所在jar包的路径信息)。而ClassLoader类中的方法可以帮助我们动态的获取这些信息:&&&&&&&&& ● public URL getResource(String name)&&&&&&&&&&&& 查找具有给定名称的资源。资源是可以通过类代码以与代码基无关的方式访问的一些数据(图像、声音、文本等)。并返回资源的URL对象。&&&&&& && ● public InputStream getResourceAsStream(String name);&&&& &&&&&&&& 返回读取指定资源的输入流。这个方法很重要,可以直接获得jar包中文件的内容。
&&&&&&&&&&(2)&ClassLoader是abstract的,不可能实例化对象,更加不可能通过ClassLoader调用上面两个方法。所以我们真正写代码的时候,是通过Class类中的getResource()和getResourceAsStream()方法,这两个方法会委托ClassLoader中的getResource()和getResourceAsStream()方法&。好了,现在我们重新写一段Resource代码,来看看上面那段费解的话是什么意思了:
//源代码2:
package edu.
import java.io.*;
import java.net.URL;
public class Resource {
void getResource() throws IOException{
//查找指定资源的URL,其中res.txt仍然开始的bin目录下
URL fileURL=this.getClass().getResource("/resource/res.txt");
System.out.println(fileURL.getFile());
public static void main(String[] args) throws IOException {
Resource res=new Resource();
res.getResource();
&运行这段源代码结果:/E:/Code_Factory/WANWAN/bin/resource/res.txt&&(../&Code_Factory/WANWAN/..&是java project所在的路径)
&&&&&&&&&&&我们将这段代码打包成ResourceJar.jar ,并将ResourceJar.jar放在其他路径下(比如 c:\ResourceJar.jar)。然后另外创建一个java project并导入ResourceJar.jar,写一段调用jar包中Resource类的测试代码:
import java.io.IOE
import edu.hxraid.R
public class TEST {
public static void main(String[] args) throws IOException {
Resource res=new Resource();
res.getResource();
这时的运行结果是:file:/C:/ResourceJar.jar!/resource/res.txt
&&&&&&&&&&&我们成功的在运行时动态获得了res.txt的位置。然而,问题来了,你是否可以通过下面这样的代码来得到res.txt文件?&&&&&&&&&&&&&&&&&& && File f=new File("C:/ResourceJar.jar!/resource/res.txt");&&&&&&&&&&& 当然不可能,因为".../ResourceJar.jar!/resource/...."并不是文件资源定位符的格式 (jar中资源有其专门的URL形式:&jar:&url&!/{entry}&)。所以,如果jar包中的类源代码用File f=new File(相对路径);的形式,是不可能定位到文件资源的。这也是为什么源代码1打包成jar文件后,调用jar包时会报出FileNotFoundException的症结所在了。
&&&&&&&&&&(3)&我们不能用常规操作文件的方法来读取ResourceJar.jar中的资源文件res.txt,但可以通过Class类的getResourceAsStream()方法来获取&,这种方法是如何读取jar中的资源文件的,这一点对于我们来说是透明的。我们将Resource.java改写成:
//源代码3:
package edu.
import java.io.*;
public class Resource {
public void getResource() throws IOException{
//返回读取指定资源的输入流
InputStream is=this.getClass().getResourceAsStream("/resource/res.txt");
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String s="";
while((s=br.readLine())!=null)
System.out.println(s);
我们将java工程下/bin目录中的edu/hxraid/Resource.class和资源文件resource/res.txt一并打包进ResourceJar.jar中,不管jar包在系统的任何目录下,调用jar包中的Resource类都可以获得jar包中的res.txt资源,再也不会找不到res.txt文件了。
阅读(...) 评论()下次自动登录
现在的位置:
& 综合 & 正文
JarFile读取jar内文件实例
JAR文件是打包基于JAVA技术的解决方案的标准方法。它允许开发者将所有相关内容(.class、图片、声音、及所有支持的文件)打包到一个文件中。JAR格式支持压缩、认证、版本号及其他很多特性。
  如果你对于常用的ZIP格式比较熟悉的话,JAR文件也就差不多。JAR文件提供一种将多个文件打包到一个文件中的方法,其中每一个文件可能独立地被压缩。JAR文件所增加的内容是manifest,它允许开发者可以提供附加的关于内容的信息。例如,manifest表明JAR文件中的哪个文件是用来运行一个的,或者库的版本号等。
  J2SEDK提供了一个JAR工具,你可以用它从控制台读写JAR文件。然而,如果你需要在程序中读写JAR文件,可能需要一点时间(本文只包含如何在程序中读写JAR文件)。好消息是你可以做到这一点,而且你不用担心解压的事,因为类库将帮助你完成这些。
  首先,通过把将JAR文件位置传给构造函数,创建一个JarFile的实例,位置可能是String或File的形式,如下:
JarFile jf = new JarFile("C:/jxl.jar");
File file = new File("C:/jxl.jar"); JarFile jarFile = new JarFile(file);
你可能注意到当文件不在class path中时,JarFile类对于从JAR中读取文件文件是很有用的。当你想指定目标JAR文件时,JarFile类对于从JAR中读取文件同样也很有用。
当然,如果JAR文件在class path中,从其中读取文件的方法比较简单,你可以用下面的方法:
URL url = ClassLoader.getSystemResource(name);
InputStream stream =
ClassLoader.getSystemResourceAsStream("javax/servlet/LocalStrings_fr.properties");
这种技术允许你从在class path中的JAR文件里读取文件。你不必指定JAR文件名。还有其他的构造函数,如认证支持,标志要删除的文件等。这些构造函数在这儿不做说明。
当你有了该JAR文件的一个引用之后,你就可以读取其文件内容中的目录信息了。JarFile的entries方法返回所有entries的枚举集合 (Enumeration)。通过每一个entry,你可以从它的manifest文件得到它的属性,任何认证信息,以及其他任何该entry的信息,如它的名字或者大小等。
Enumeration enu = jf.entries();while (enu.hasMoreElements()) {JarEntry element = (JarEntry) enu.nextElement();
String name = element.getName();
Long size = element.getSize();
Long time = element.getTime();
Long compressedSize = element.getCompressedSize();
System.out.print(name+"/t");
System.out.print(size+"/t");
System.out.print(compressedSize+"/t");
System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(new Date(time)));}
如果你用J2SE1.5.0中的jce.jar作为参数运行上面的代码,你将看到类似于下面的输出(...部分为省略掉的输出):
META-INF/MANIFEST.MF
META-INF/JCE_RSA.SF
META-INF/JCE_RSA.RSA
javax/crypto/
javax/crypto/interfaces/
javax/crypto/interfaces/DHKey.class
javax/crypto/interfaces/DHPublicKey.class
javax/crypto/interfaces/DHPrivateKey.class
javax/crypto/interfaces/PBEKey.class
javax/crypto/SecretKey.class
javax/crypto/spec/
13:11:12... ...
注意输出最开始的META-INF行。这是manifest和安全认证信息。0字节的entries不是文件,但是有点相当于目录。
为了从JAR文件中真正读取一个指定的文件,你必须到其entry的InputStream。这和JarEntry不一样。这是因为JarEntry只是包含该entry的有关信息,但是并不实际包含该entry的内容。这和File和FileInputStream的区别有点儿相似。访问文件没有打开文件,它只是从目录中读取了该文件的信息。下面是如何得到entry的InputStream:
InputStream input = jarFile.getInputStream(entry);
当你有了输入流,你就可以像读取其他流一样读取它。在文本流中(text stream),记得使用读取器(Reader)从流中取得字符。对于面向字节的流,如图片文件,直接读取就行了。
下面的程序演示如何从JAR文件中读取文件。指定JAR文件的名称,要读取的文件的名称(打包JAR文件中的某一个文件)作为参数来调用该程序。要读取的文件应该有一个文本类型的。
   import java.io.*;    import java.util.jar.*;      public class JarRead {     public static void main (String args[])       throws IOException {      if (args.length != 2) {       System.out.println(        "Please provide a JAR filename and file to read");       System.exit(-1);      }      JarFile jarFile = new JarFile(args[0]);      JarEntry entry = jarFile.getJarEntry(args[1]);      InputStream input = jarFile.getInputStream(entry);      process(input);      jarFile.close();     }       private static void process(InputStream input)       throws IOException {      InputStreamReader isr =      new InputStreamReader(input);      BufferedReader reader = new BufferedReader(isr);      S      while ((line = reader.readLine()) != null) {       System.out.println(line);      }      reader.close();     }    }
假设在myfiles.jar文件中有一个spider.txt文件,spider文件的内容如下:
   The itsy bitsy spider   Ran up the water spout   Down came the rain and   Washed the spider out
  你可以通过下面的命令来显示该文本文件的内容:
java JarRead myfiles.jar spider.txt
原帖地址:
  有关JAR文件的更多内容,请参考JAR文件规范。
&&&&推荐文章:
【上篇】【下篇】2709人阅读
java(34)
public static void main(String[] args) throws IOException {
String jarPath = &omc-pm-server-eOMC910V100R001C00SPC100B020.jar&;
String res = readFileFromJar(jarPath,&pm.hbm.xml&);
System.out.println(res);
* 从jar中获取指定名称的文本文件
* @param jarPath
* @param name
* @throws IOException
public static String readFileFromJar(String jarPath ,String name) throws IOException {
JarFile jf = new JarFile(jarPath);
Enumeration&JarEntry& jfs = jf.entries();
StringBuffer sb
= new StringBuffer();
while(jfs.hasMoreElements())
JarEntry jfn = jfs.nextElement();
if(jfn.getName().endsWith(name))
InputStream is = jf.getInputStream(jfn);
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buf = new byte[is.available()];
while(bis.read(buf)!=-1)
sb.append(new String(buf).trim());
bis.close();
is.close();
return sb.toString();
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:127391次
积分:2109
积分:2109
排名:第14215名
原创:82篇
评论:23条
(1)(4)(2)(1)(1)(1)(7)(1)(9)(5)(6)(11)(6)(2)(1)(2)(3)(2)(6)(9)(2)
转载名人的文章对 jar内的某个txt文件进行读
写 - 开源中国社区
当前访客身份:游客 [
当前位置:
本人java小菜。基本之前没怎么用过java,但是现在要做点事,必须用java,因为是引用人家提供的一个jar包进行开发。
问题是这样的:我想对人家提供的jar包里的某个txt文件进行读 和 &写。
人家提供一个jar包,里面有一些.class 文件父类和txt文件是数据。父类中有对制定名字的txt文件进行读取并运算的功能。
现在我想继承父类,然后做点自己的事。我要对一些新的数据进行运算,所以,我必须先将我的数据替换掉jar包内的txt文件的内容。然后再进行操作。
举例来说:人家给我一个jar包,里面有个.class 能实现两个数相加的功能。但是相加的两个数,必须从jar包中的input.txt进行读写。我要写个实现3个数相加的函数。然后我必须也要从input.txt里读参数。于是,我得对input.txt进行改写,用程序自动完成。但是,input.txt在jar包内,怎么改写啊?
不知道问题描述清楚没啊。。。在线等啊。您回复会及时发到我的邮箱啊。一直在关注啊。。。谢谢各位啦。
---------------问题补充---------------
:还有一个问题,在程序运行过程中,jar是被加载到虚拟机里的,是否对其写会涉及到锁的问题? 我现在在网上查,用InputStream is=this.getClass().getResourceAsStream("my.txt");能对jar内的文件进行读取了
共有7个答案
<span class="a_vote_num" id="a_vote_num_
直接贴代码吧:
// 判断目录是否存在
File baseDir = new File(baseDirName);
if (!baseDir.exists() || !baseDir.isDirectory()) {
System.out.println(&文件查找失败:& + baseDirName + &不是一个目录!&);
String[] filelist = baseDir.list();
for (int i = 0; i & filelist. i++) {
if (filelist[i].contains(&txtjar&)) {//查找含有你的txt的jar包
JarFile localJarFile = new JarFile(new File(baseDirName
+ File.separator + filelist[i]));
Enumeration&JarEntry& entries = localJarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
String entryName = jarEntry.getName();
if (jarEntry.isDirectory()) {
// System.out.println(entryName);
} else if (entryName.endsWith(&.txt&)) {
//在此处找到你的txt进行处理 }
} catch (IOException e) {
e.printStackTrace();
写的话麻烦些,需要解压后修改完了再打成jar包,直接用解压软件解压即可,修改完成后用命令行或者eclipse导成新jar
<span class="a_vote_num" id="a_vote_num_
感觉应该是只能读吧,没有听说可以写jar中的文件,除非是使用zip功能,写jar中的文件.
--- 共有 1 条评论 ---
zip什么功能?有具体一点的介绍吗?
(4年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
引用来自“缪斯的情人”的答案直接贴代码吧:
// 判断目录是否存在
File baseDir = new File(baseDirName);
if (!baseDir.exists() || !baseDir.isDirectory()) {
System.out.println(&文件查找失败:& + baseDirName + &不是一个目录!&);
String[] filelist = baseDir.list();
for (int i = 0; i & filelist. i++) {
if (filelist[i].contains(&txtjar&)) {//查找含有你的txt的jar包
JarFile localJarFile = new JarFile(new File(baseDirName
+ File.separator + filelist[i]));
Enumeration&JarEntry& entries = localJarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
String entryName = jarEntry.getName();
if (jarEntry.isDirectory()) {
// System.out.println(entryName);
} else if (entryName.endsWith(&.txt&)) {
//在此处找到你的txt进行处理 }
} catch (IOException e) {
e.printStackTrace();
写的话麻烦些,需要解压后修改完了再打成jar包,直接用解压软件解压即可,修改完成后用命令行或者eclipse导成新jar问题是这样,我的程序在运行的时候,加载了jar包。我是边运行我的程序,边修改被加载的jar包的内容。
首先感谢您的回答,这么快就有答复,OSC真给力。
如果按照您说的,修改完了重新打包成jar,可能不好使。
还有,您能稍微再完善一下您的代码吗?比如,我就是想往名为myjar的jar包中,folder/1.txt中写一行“I love OSC”。您能稍微改写一下您的程序吗?我是小菜,目前只能参考别人的程序来改写。。。所以。。麻烦了。
--- 共有 1 条评论 ---
我提供的代码可以按照你的jar名字查找某一个jar包的,看注释。你如果是动态修改jar中的内容,那估计java办不到
(4年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
你修改的是jar文件中的file.txt文件而不是class.JarURLConnection可以办到.
public void testUri() throws Exception {
URL url = new URL(&jar:file:E:/dubbo-2.5.3.jar!/META-INF/MANIFEST.MF&);
JarURLConnection jarConnection = (JarURLConnection)url.openConnection();
InputStream in = jarConnection.getInputStream();//(&!/META-INF/MANIFEST.MF&));
System.out.println(IOUtils.copy(in, System.out));
} 有了jarConnection你可以取得InputStream和OutputStream了.
--- 共有 4 条评论 ---
您好,前两天我有点急事,没来的急试。今天试了一下,发现这个只能获取InputStream ,不能获取OutputStream.抛出异常如下:java.net.UnknownServiceException: protocol doesn't support output
at java.net.URLConnection.getOutputStream(Unknown Source)
(4年前)&nbsp&
: 更简单的写是
InputStream is=this.getClass().getResourceAsStream("/sgip/test.txt");
(4年前)&nbsp&
: 只支持读,不支持写.修改还是需要使用zip
(4年前)&nbsp&
十分感谢,我试一下。嘿嘿。
(4年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
<span class="a_vote_num" id="a_vote_num_
怎么会有这么奇葩的需求?
那个input.txt既然不是只读的,放到jar包里做什么?
既然放到jar包里了,那就是只读的,你把它的内容copy出来放到一个资源文件里,然后操作这个资源文件不行吗,为什么一定要修改jar包?
<span class="a_vote_num" id="a_vote_num_
引用来自“sherlokk”的答案 怎么会有这么奇葩的需求?
那个input.txt既然不是只读的,放到jar包里做什么?
既然放到jar包里了,那就是只读的,你把它的内容copy出来放到一个资源文件里,然后操作这个资源文件不行吗,为什么一定要修改jar包? 嘿嘿,是这样的。这个是人家发布的,里面有函数,有数据。数据是放在txt里的。我现在想测试更多的数据。但是,人家在程序中写死了,数据只能从jar中的几个文件内读取。所以,有了这个奇葩的需求。
--- 共有 1 条评论 ---
把input.txt从jar包中移出来,放到同名目录下。
比如它是com.osc.input.txt。你就在自己的项目路径下创建com.osc,然后把input.txt从那个jar包里移出来,放到这个目录下。
(4年前)&nbsp&
更多开发者职位上
有什么技术问题吗?
shewa的其它问题
类似的话题java如何读JAR包里的配置文件_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
java如何读JAR包里的配置文件
上传于||文档简介
&&j&#8203;a&#8203;v&#8203;a&#8203;如&#8203;何&#8203;读&#8203;J&#8203;A&#8203;R&#8203;包&#8203;里&#8203;的&#8203;配&#8203;置&#8203;文&#8203;件
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩1页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢

我要回帖

更多关于 jar包中读取配置文件 的文章

 

随机推荐