JAR文件是打包基于JAVA技术的解决方案的标准方法。它允许开发者将所有相关内容(.class、图片、声音、及所有支持的文件)打包到一个文件中。JAR格式支持压缩、认证、版本号及其他很多特性。
如果你对于常用的ZIP格式比较熟悉的话,JAR文件也就差不多。JAR文件提供一种将多个文件打包到一个文件中的方法,其中每一个文件可能独立地被压缩。JAR文件所增加的内容是manifest,它允许开发者可以提供附加的关于内容的信息。例如,manifest表明JAR文件中的哪个文件是用来运行一个程序的,或者库的版本号等。
J2SEDK提供了一个JAR工具,你可以用它从控制台读写JAR文件。然而,如果你需要在程序中代码读写JAR文件,可能需要一点时间(本文只包含如何在程序中读写JAR文件)。好消息是你可以做到这一点,而且你不用担心解压的事,因为类库将帮助你完成这些。
首先,通过把将JAR文件位置传给构造函数,创建一个JarFile的实例,位置可能是String或File的形式,如下:
或者:
你可能注意到当文件不在class path中时,JarFile类对于从JAR中读取文件文件是很有用的。当你想指定目标JAR文件时,JarFile类对于从JAR中读取文件同样也很有用。
当然,如果JAR文件在class path中,从其中读取文件的方法比较简单,你可以用下面的方法:
或者:
这种技术允许你从在class path中的JAR文件里读取文件。你不必指定JAR文件名。还有其他的构造函数,如认证支持,标志要删除的文件等。这些构造函数在这儿不做说明。
当你有了该JAR文件的一个引用之后,你就可以读取其文件内容中的目录信息了。JarFile的entries方法返回所有entries的枚举集合 (Enumeration)。通过每一个entry,你可以从它的manifest文件得到它的属性,任何认证信息,以及其他任何该entry的信息,如它的名字或者大小等。
如果你用J2SE1.5.0中的jce.jar作为参数运行上面的代码,你将看到类似于下面的输出(...部分为省略掉的输出):
注意输出最开始的META-INF行。这是manifest和安全认证信息。0字节的entries不是文件,但是有点相当于目录。
为了从JAR文件中真正读取一个指定的文件,你必须到其entry的InputStream。这和JarEntry不一样。这是因为JarEntry只是包含该entry的有关信息,但是并不实际包含该entry的内容。这和File和FileInputStream的区别有点儿相似。访问文件没有打开文件,它只是从目录中读取了该文件的信息。下面是如何得到entry的InputStream:
当你有了输入流,你就可以像读取其他流一样读取它。在文本流中(text stream),记得使用读取器(Reader)从流中取得字符。对于面向字节的流,如图片文件,直接读取就行了。
下面的程序演示如何从JAR文件中读取文件。指定JAR文件的名称,要读取的文件的名称(打包JAR文件中的某一个文件)作为参数来调用该程序。要读取的文件应该有一个文本类型的。
假设在myfiles.jar文件中有一个spider.txt文件,spider文件的内容如下:
你可以通过下面的命令来显示该文本文件的内容:
有关JAR文件的更多内容,请参考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);
JarFile jarFile = new JarFile(file);
当然,如果JAR文件在class path中,从其中读取文件的方法比较简单,你可以用下面的方法:
URL url
=
ClassLoader.getSystemResource(name);
InputStream stream
=
ClassLoader.getSystemResourceAsStream("javax/servlet/LocalStrings_fr.properties");
ClassLoader.getSystemResourceAsStream("javax/servlet/LocalStrings_fr.properties");
当你有了该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)));
}
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)));
}
META
-
INF
/
MANIFEST.MF
5640
2028
2004
-
04
-
20
13
:
11
:
28
META - INF / JCE_RSA.SF 5546 2032 2004 - 04 - 20 13 : 11 : 28
META - INF / JCE_RSA.RSA 2022 1307 2004 - 04 - 20 13 : 11 : 28
META - INF / 0 2 2004 - 04 - 20 13 : 11 : 12
javax / 0 0 2004 - 04 - 20 13 : 11 : 12
javax / crypto / 0 0 2004 - 04 - 20 13 : 11 : 12
javax / crypto / interfaces / 0 0 2004 - 04 - 20 13 : 11 : 12
javax / crypto / interfaces / DHKey. class 210 187 2004 - 04 - 20 13 : 11 : 12
javax / crypto / interfaces / DHPublicKey. class 330 271 2004 - 04 - 20 13 : 11 : 12
javax / crypto / interfaces / DHPrivateKey. class 332 270 2004 - 04 - 20 13 : 11 : 12
javax / crypto / interfaces / PBEKey. class 333 280 2004 - 04 - 20 13 : 11 : 12
javax / crypto / SecretKey. class 232 211 2004 - 04 - 20 13 : 11 : 12
javax / crypto / spec / 0 0 2004 - 04 - 20 13 : 11 : 12
... ...
META - INF / JCE_RSA.SF 5546 2032 2004 - 04 - 20 13 : 11 : 28
META - INF / JCE_RSA.RSA 2022 1307 2004 - 04 - 20 13 : 11 : 28
META - INF / 0 2 2004 - 04 - 20 13 : 11 : 12
javax / 0 0 2004 - 04 - 20 13 : 11 : 12
javax / crypto / 0 0 2004 - 04 - 20 13 : 11 : 12
javax / crypto / interfaces / 0 0 2004 - 04 - 20 13 : 11 : 12
javax / crypto / interfaces / DHKey. class 210 187 2004 - 04 - 20 13 : 11 : 12
javax / crypto / interfaces / DHPublicKey. class 330 271 2004 - 04 - 20 13 : 11 : 12
javax / crypto / interfaces / DHPrivateKey. class 332 270 2004 - 04 - 20 13 : 11 : 12
javax / crypto / interfaces / PBEKey. class 333 280 2004 - 04 - 20 13 : 11 : 12
javax / crypto / SecretKey. class 232 211 2004 - 04 - 20 13 : 11 : 12
javax / crypto / spec / 0 0 2004 - 04 - 20 13 : 11 : 12
... ...
为了从JAR文件中真正读取一个指定的文件,你必须到其entry的InputStream。这和JarEntry不一样。这是因为JarEntry只是包含该entry的有关信息,但是并不实际包含该entry的内容。这和File和FileInputStream的区别有点儿相似。访问文件没有打开文件,它只是从目录中读取了该文件的信息。下面是如何得到entry的InputStream:
InputStream input
=
jarFile.getInputStream(entry);
下面的程序演示如何从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);
String line;
while ((line = reader.readLine()) != null) ...{
System.out.println(line);
}
reader.close();
}
}
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);
String line;
while ((line = reader.readLine()) != null) ...{
System.out.println(line);
}
reader.close();
}
}
The itsy bitsy spider
Ran up the water spout
Down came the rain and
Washed the spider out
Ran up the water spout
Down came the rain and
Washed the spider out
你可以通过下面的命令来显示该文本文件的内容:
java JarRead myfiles.jar spider.txt
有关JAR文件的更多内容,请参考JAR文件规范。