📄 自解压的jar实现原理.htm
字号:
<P><B><FONT size=3>作者:Turbo Chen</FONT></B></P>
<P><B><FONT size=3>日期:2004/2/8</FONT></B></P>
<P>
在网络上,有些java程序的提供者将他们的java安装程序打包成一个jar文件的形式。当运行时,自动将jar中的程序解压出来安装到使用者的电脑上。他们是如何做到这些的呢?现在我们就来解开这个迷,让大家了解如果制作这样的jar文件。</P>
<P>
首先,我们来回忆一下,以前我们打包jar时,通常将class程序要用到的资源如*.gif图片、*.xml配置文件等都打包在同一个jar中。而程序读取它们时,无外乎以下几种情况:</P>
<P>getClass().getResource(String
name)<BR>getClass().getresourceAsStream(String name)</P>
<P>由于Class的这两个方法实际上就是调用了ClassLoader的相应方法,所以可以干脆用下面的方法:</P>
<P><FONT
size=2>ClassLoader.getSystemClassLoader().getResource(String
name)<BR>ClassLoader.getSystemClassLoader().getResourceAsStream(String
name)</FONT></P>
<P><FONT size=2>getResource可以取得相关资源的URL,
这在使用图片资源时很有用。而getResourceAsStream可以取得资源的输入流,这个通常在读取jar中的xml配置文件时用到。</FONT></P>
<P><FONT
size=2>其实讲到这里我们就可以明白那些可以自动解压安装的jar是怎么一回事了----它就是使用了getresourceAsStream方法。</FONT></P>
<P><FONT size=2>下面我们来详细描述怎么实现一个通用的自动解压安装的jar程序。</FONT></P>
<P><FONT size=2>为了使这个程序尽可能的通用,我将它设计成下面的结构:</FONT></P>
<P><IMG height=464 src="自解压的jar实现原理_files/figure.jpg" width=437
border=0></P>
<P>Resource包含要安装的资源的信息,通过getName方法可以取得资源名称,通过getDistPath方法要被安装的路径。相应的resourceCollectioin是Resource的集合。</P>
<P>InstallConfig是要安装资源的配置信息,为了通用的目的,将资源配置信息写入一名为install-config.xml的文件。InstallConfig初始化时,会载入配置文件中的信息。将其实例化成Resource集合:</P><FONT
size=2>
<BLOCKQUOTE><PRE> ...
InputStream input =
ClassLoader.getSystemClassLoader().getResourceAsStream(CONFIG);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document configDoc = builder.parse(input);
Element eConfig = (Element) configDoc.getElementsByTagName(</FONT><FONT color=#2a00ff size=2>"install-config"</FONT><FONT size=2>).item(0);
resourceBase = eConfig.getAttribute(</FONT><FONT color=#2a00ff size=2>"resourcebase"</FONT><FONT size=2>);
NodeList eResources = configDoc.getElementsByTagName(</FONT><FONT color=#2a00ff size=2>"resource"</FONT><FONT size=2>);
</FONT><B><FONT color=#7f0055 size=2>for</FONT></B><FONT size=2> ( </FONT><B><FONT color=#7f0055 size=2>int</FONT></B><FONT size=2>
i=0;i<eResources.getLength();i++ )
{
Element eResource = (Element) eResources.item(i);
Resource res = </FONT><B><FONT color=#7f0055 size=2>new</FONT></B><FONT size=2>
Resource(eResource.getAttribute(</FONT><FONT color=#2a00ff size=2>"name"</FONT><FONT size=2>),PathUtil.replaceAll(eResource.getAttribute(</FONT><FONT color=#2a00ff size=2>"dist"</FONT><FONT size=2>)));
resSet.addResource(res);
}
...
</PRE></BLOCKQUOTE></FONT>
<P>相关的install-config.xml文件格式如下:</P><FONT color=#0000ff size=1>
<BLOCKQUOTE>
<P><</FONT><FONT color=#800000
size=1>install-config</FONT><FONT color=#ff0000 size=1>
resourcebase</FONT><FONT color=#0000ff size=1>="</FONT><FONT
size=1>res/</FONT><FONT color=#0000ff size=1>"></P></FONT><FONT
size=1>
<P></FONT><FONT color=#0000ff size=1>
<</FONT><FONT color=#800000 size=1>resource</FONT><FONT
color=#ff0000 size=1> name</FONT><FONT color=#0000ff
size=1>="</FONT><FONT face=Arial size=1>testA</FONT><FONT
size=1>.</FONT><FONT face=Arial size=1>txt</FONT><FONT
color=#0000ff size=1>"</FONT><FONT color=#ff0000 size=1>
dist</FONT><FONT color=#0000ff size=1>="</FONT><FONT
size=1>${user.dir}/</FONT><FONT color=#0000ff
size=1>"/></P></FONT><FONT size=1>
<P></FONT><FONT color=#0000ff size=1>
<</FONT><FONT color=#800000 size=1>resource</FONT><FONT
color=#ff0000 size=1> name</FONT><FONT color=#0000ff
size=1>="</FONT><FONT face=Arial size=1>testB</FONT><FONT
size=1>.</FONT><FONT face=Arial size=1>txt</FONT><FONT
color=#0000ff size=1>"</FONT><FONT color=#ff0000 size=1>
dist</FONT><FONT color=#0000ff size=1>="</FONT><FONT
size=1>c:/</FONT><FONT color=#0000ff size=1>"/></P>
<P></</FONT><FONT color=#800000
size=1>install-config</FONT><FONT color=#0000ff
size=1>></P></BLOCKQUOTE></FONT>
<P>其中<BR>resourcebase 是要安装资源在jar中的基准位置。<BR>name 是资源名。<BR>dist:
是资源将被安装到的目标目录。<BR>目录支持三种类型的环境变量,分别是:<BR>${user.dir}
是用户程序运行的路径。<BR>${user.home} 是用户的主目录,对于window2000用户来说,它位于C:/Documents
and Settings/Administrator。<BR>${java.home} 是JRE安装的主目录。</P>
<P>**注意:对于目录名,必须以"/"分隔,并以"/"结尾。</P>
<P> </P>
<P>AutoInstaller是主程序,它读取InstallConfig中的资源配置信息,并负责这些资源的自动解压和安装的工作,实现的代码很简单:</P>
<BLOCKQUOTE><PRE><FONT size=2>
...
ClassLoader scl = ClassLoader.getSystemClassLoader();
</FONT><FONT color=#3f7f5f size=2>//读取要安装资源的配置信息。</FONT><FONT size=2>
String base = installConfig.getResourceBase();
ResourceCollection resources = InstallConfig.getInstance().getResources();
</FONT><B><FONT color=#7f0055 size=2>for</FONT></B><FONT size=2> ( </FONT><B><FONT color=#7f0055 size=2>int</FONT></B><FONT size=2> i=0;i<resources.size();i++ )
{
Resource res = resources.getResource(i);
File distDir = </FONT><B><FONT color=#7f0055 size=2>new</FONT></B><FONT size=2> File(res.getDistPath());
File distFile = </FONT><B><FONT color=#7f0055 size=2>new</FONT></B><FONT size=2> File(distDir,res.getName());
InputStream srcFile = scl.getResourceAsStream(base+res.getName());
</FONT><B><FONT color=#7f0055 size=2>if</FONT></B><FONT size=2> ( !distFile.exists() && srcFile!=</FONT><B><FONT color=#7f0055 size=2>null</FONT></B><FONT size=2> )
{
<FONT color=#3f7f5f size=2>// 将文件释放庢指定位置, 详细代码看源程序</FONT>
extractFile(srcFile, distFile);
}
}
...
</FONT></PRE></BLOCKQUOTE>
<P>程序实现起来非常简单,关键是打包时,各个文件的位置,以下再来个例子说明一下:</P><PRE> [myProj]
[src]
install-config.xml
[dist]
[res]
在此目录结构是,myProj是我项目的主目录,src是本文源程序位置,install-config.xml也在其中。
dist是打包后的目录位置。
res是我们要进行自动解压安装的相关文件的位置,所有要安装的文件就在其中,我提供的build.xml可以自动将其打进包内。
</PRE>
<P>为配合此程序,我另外制作了方便打包的ant编译脚本文件build.xml,在我文后提供的下载包有详细的用法说明。欢迎大家下载使用。</P>
<P><A
href="http://turbojava.blogdriver.com/diary/turbojava/inc/autoinstaller.rar"><U>下载全部源文件</U></A></P></FONT></TD></TR>
<TR>
<TD align=right>
<SCRIPT language=JavaScript>
<!-- Begin
if (window.print) {
document.write('【<a href="#" onClick="javascript:window.print()"><font color=cc0000>打印本文</font></a>】 ');
}
// End -->
</SCRIPT>
【<A href="http://www.ok335.com/javawork/comment.asp"
target=_blank><FONT color=#cc0000>发表评论</FONT></A>】【<A
href="javascript:window.close()"><FONT
color=#cc0000>关闭窗口</FONT></A>】</TD></TR></TBODY></TABLE>
<HR>
<BR>
<TABLE cellSpacing=1 cellPadding=0 width=800 align=center bgColor=#6699cc
border=0>
<TBODY>
<TR>
<TD bgColor=#eeeeee height=23><FONT color=#003366>相关新闻</FONT></TD></TR>
<TR>
<TD bgColor=#f0f3f7>
<SCRIPT language=JavaScript
src="自解压的jar实现原理_files/about.htm"></SCRIPT>
</TD></TR></TBODY></TABLE>
<TR vAlign=top align=left>
<TD colSpan=2>
<SCRIPT language=JavaScript src="自解压的jar实现原理_files/end.js"></SCRIPT>
<TR bgColor=#ffffff>
<TD bgColor=#cccccc height=27> </TR></TBODY></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -