Friday, September 15, 2006


  之前遇到这样一个需求,需要在上传一个压缩包,同时解压到一个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