
之前遇到这样一个需求,需要在上传一个压缩包,同时解压到一个WEB应用的目录下,方便链接。在这里,我把
我们的探索过程整理一下:
OP : Windows XP
IDE : Eclipse 3.2
WEB Server : Tomcat 5.5
JDK : jdk-1_5_0_06-windows-i586-p
第一个冒出来的想法是:上传ZIP压缩格式的包,利用import java.util.zip.*;包里的类,将压缩文件以流读出来,
从新写成文件,比较成功,文件到达目的地,而且结构完整,但我们在检验中发现,一些稍微大一点的.jpg & .gjf 的图
片文件,在解压的时候坏了,无法预览。而这是客户所不允许的问题,于是,这个方法被排除。解压算法如下:
// 解压缩
FileInputStream fi = new FileInputStream( "e:\\test.zip" );
CheckedInputStream csumi = new CheckedInputStream( fi , new Adler32() );
ZipInputStream in2 = new ZipInputStream( new BufferedInputStream ( csumi ) );
ZipEntry ze;
while ( ( ze = in2.getNextEntry()) != null ) {
System.out.println ( "Reading file " + ze );
int x ;
while ((x = in2.read() ) != -1)
System.out.write( x );
}
System.out.println( "Checksum:" + csumi.getChecksum().getValue() );
in2.close();
刚好那段时间是暑假,待在学校,而且没有网,每次查资料都要到机房。Kryptonum带来了一个解决办法,有人
利用winrar软件中一个应用程序UnRAR.exe解压文件。使用java.lang.RunTime对象创建一个进程,执行一些命令—
—那么我们便可以尝试利用绝对路径解压到相应目录,我开始研究winrar带的控制台手册。这条命令,貌似有意思:
...>应用程序路径\UnRAR.exe x 压缩文件路径 目标路径 ,例如:...>e:\UnRAR.exe x e:\a.rar e:\upload
非常顺利,我们得到了想要的结果,文件结构完整,而且图片也没有被压坏。可以利用,ServletContext对象的
getRealPath(...)获取到绝对路径,那么就如在dos环境下使用解压命令一样了。然而,问题又出现了,我们安装的
Tomcat 5.5默认路径是:c:\Program Files\Apache Software Foundation\Tomcat 5.5 ,如果部署在Tomcat下,
那么路径上文件名是有空格的,那么会被系统自动将空格前一截截断,便发生类似如下错误(dos下模拟):
C:\Documents and Settings\Lisliefor>e:\a b\UnRAR.exe x e:\upload\1.rar e:\upload
'e:\a' 不是内部或外部命令,也不是可运行的程序或批处理文件。
蓝色字体a b间,被截断了。当然,这并不是主要问题(在后面得到解决)。当我们覆盖上传的时候,发现这个进
程一直占用CPU资源,导致机器卡得无法动弹。后来我在dos环境下,模拟该情况,发现因为解压后文件要覆盖以前
的。每覆盖一个文件都要有一个询问,如下:
C:\Documents and Settings\Lisliefor>e:\a\UnRAR.exe x e:\upload\1.rar e:\upload
UNRAR 3.60 免费软件 版权 (C) 1993-2006 Alexander Roshal所有
正在从 e:\upload\1.rar 中解压
e:\upload\cgolden.pdf 已经存在,覆盖它吗?[Y]-是, [N]-否, [A]-全部, [E]-从不, [R]-改名, [Q]-退出 y
正在解压 e:\upload\cgolden.pdf 完成
e:\upload\爱书吧 电子书 教程 让更多人 读更多的书.url 已经存在,覆盖它吗?[Y]-是, [N]-否, [A]-全部, [E]-从
不, [R]-改名, [Q]-退出
需要输入y,然后回车,才能继续。当时被绝对路径带空格的问题,困扰很久!想到过使用转义字符,不过浅尝则
止!
也尝试过解压命令中,解压到当前目录,配合着java.lang.RunTime对象exec(String)方法的重载方法(String
[] , File , String[])查一下API便知,File对象 指定了新子进程的工作目录。如果将它设定为目标路径,那么貌似可以
解决问题,同时也避免了路径带空格的问题。新的问题又出现了,这样解压,破坏了原本的文件结构——压缩文件下最
底层的文件被解压出来,放在一起。急病乱投医,当时还研究了利用winrar的两个文件Rar.exe和WinCon.SFX,将文
件制作成自解压文件,同样,无可避免路径空格问题。
讽刺的是,最后没有办法,在部署服务器的时候,重新安装tomcat,将安装路径上的空格全部用下划线代
替。 :)
后来在jcsdn上逛,看到一张帖子,后来查一下API,发现那时候自己多令人......
exec(String[] cmdarray) 在单独的进程中执行指定命令和变量:
//创建压缩进程
String[] s = new String[] { "d:\\Software\\UnRar\\UnRAR.exe" , "x" , "e:\\yixing\\11.rar" , "e:\\a" };
或者使用转义字符:
exec ( d:\\Software\\UnRar\\UnRAR.exe x \"e:\\yi xing\\11.rar\" e:\\a);
而且重上传文件覆盖的问题,也解决了,我写了一个删除文件的类,在解压前,先将相应文件删除。下面将工具类
的代码贴出来,见顶上!

0 Comments:
Post a Comment
Links to this post:
Create a Link
<< Home