从Java的jar文件中读取数据的方法
本文实例讲述了从Java的jar文件中读取数据的方法。分享给大家供大家参考。具体如下:
Java档案(JavaArchive,JAR)文件是基于Java技术的打包方案。它们允许开发人员把所有相关的内容(.class、图片、声音和支持文件等)打包到一个单一的文件中。JAR文件格式支持压缩、身份验证和版本,以及许多其它特性。
从JAR文件中得到它所包含的文件内容是件棘手的事情,但也不是不可以做到。这篇技巧就将告诉你如何从JAR文件中取得一个文件。我们会先取得这个JAR文件中的文件目录,然后读取指定的文件。
如果你熟悉常见的ZIP格式,你会发现JAR文件和它区别不大。JAR文件提供了一个把多个文件打包到一个文件中的方法,而且被打包的每个文件都可以分别压缩。JAR文件可以添加一个被称为manifest 的东西,它们允许开发人员添加与内容有关的其它信息。例如,manifest可以指明由JAR文件中的哪一个文件开始运行应用程序,或者指定这个库的版本等。
Java2SDK标准版提供了一个jar工具,你可以通过它在控制台下读写JAR文件。然后,也许有些时候你想在你的程序中读写JAR文件。(这篇技巧仅涉及了在程序中读JAR文件的内容。)非常高兴,你可以做到,并且不需要考虑解压的问题,因为类库已经帮你处理了。你要用到的类都在java.util.jar包中。这里要用到的主要的类是JarFile类,它是一个.jar文件自身的引用。其中的每个文件则由JarEntry引用。
现在开始,传递一个参数给JarFile的构造函数创建一个JarFile实例,这个参数可能是String也可以是File,它是一个.jar文件的位置:
JarFilejarFile=newJarFile("thefile.jar");
或者
Filefile=newFile("thefile.jar"); JarFilejarFile=newJarFile(file);
它还有其它一些构造函数,支持身份验证和标记文件为删除。不过这里不会涉及到这些构造函数。
在你得到一个JAR文件的引用之后,你就可以读了其内容的目录了。JarFile的entries方法返回一个所有条目的Enumeration对象,你还可以从manifest文件中获得它的属性、身份验证信息以及其它的信息,如条目的名称和大小。
//译者注:enum在Java5.0中是关键字,所以该例在5.0中应该编译失败 //但英文原著发表于Java5.0出现之前,所以可以使用enum作变量名 //为忠于原著,这里未作修改 Enumerationenum=jarFile.entries(); while(enum.hasMoreElements()){ process(enum.nextElement()); }
以前提到过,每个个体都是一个JarEntry。这个类有一些诸如getName、getSize和getCompressedSize的方法。
让我们举例说明如何在程序中使用这些特性。下面的程序显示JAR文件的内容列表及各项的名称、大小和压缩后的大小。(这很类似于使用带"t"和"v"参数的jar命令。)
importjava.io.*; importjava.util.*; importjava.util.jar.*; publicclassJarDir{ publicstaticvoidmain(Stringargs[]) throwsIOException{ if(args.length!=1){ System.out.println("PleaseprovideaJARfilename"); System.exit(-1); } JarFilejarFile=newJarFile(args[0]); Enumerationenum=jarFile.entries(); while(enum.hasMoreElements()){ process(enum.nextElement()); } } privatestaticvoidprocess(Objectobj){ JarEntryentry=(JarEntry)obj; Stringname=entry.getName(); longsize=entry.getSize(); longcompressedSize=entry.getCompressedSize(); System.out.println(name+""+size+""+compressedSize); } }
如果你用J2SE1.4.1中的jce.jar来试验上述的JarDir程序,你应该看像下面那样的输出(在...处应该显示更多文件):
META-INF/MANIFEST.MF53151910 META-INF/4JCEJARS.SF53681958 META-INF/4JCEJARS.DSA22071503 META-INF/02 javax/00 javax/crypto/00 javax/crypto/interfaces/00 javax/crypto/interfaces/DHKey.class209185 javax/crypto/interfaces/DHPublicKey.class265215 javax/crypto/interfaces/DHPrivateKey.class267215 javax/crypto/interfaces/PBEKey.class268224 javax/crypto/SecretKey.class167155 ...
注意输入内容顶部包含META-INF的那几行,这是menifest和安全验证信息。其中大小为0的项不是文件,而是目录。
要真正从JAR文件中读取文件内容,你必须获得相应条目的InputStream。这不同于JarEntry。JarEntry仅包括了入口信息,却并未包含实际的内容。这很像File和FileInputSteram的区别。只访问File,永远不会打开相应的文件,它只读取在目录中的信息。下面告诉你如何从一个条目得到InputStream:
InputStreaminput=jarFile.getInputStream(entry);
得到输入流之后,你只需要像读其它流一样读它就行了。如果是一个文本流,要记得使用一个Reader来从流中获取字符。而对于字节流,如图片,则只好直接读取。
下面的程序演示了从一个JAR文件中读取内容。运行程序时,需要指定要从JAR文件中读取的文件名,这个文件必须是文本文件类型。
importjava.io.*; importjava.util.jar.*; publicclassJarRead{ publicstaticvoidmain(Stringargs[]) throwsIOException{ if(args.length!=2){ System.out.println("PleaseprovideaJARfilenameandfiletoread"); System.exit(-1); } JarFilejarFile=newJarFile(args[0]); JarEntryentry=jarFile.getJarEntry(args[1]); InputStreaminput=jarFile.getInputStream(entry); process(input); jarFile.close(); } privatestaticvoidprocess(InputStreaminput) throwsIOException{ InputStreamReaderisr= newInputStreamReader(input); BufferedReaderreader=newBufferedReader(isr); Stringline; while((line=reader.readLine())!=null){ System.out.println(line); } reader.close(); } }
假设你有一个名为myfiles.jar的JAR文件,其中有一个名为spider.txt文本文件,再假设那个 pider.txt包含如下文本:
Theitsybitsyspider Ranupthewaterspout Downcametherainand Washedthespiderout
运行下面的命令以显示JAR文件中该文本文件的内容:
javaJarReadmyfiles.jarspider.txt
希望本文所述对大家的java程序设计有所帮助。