代码之家  ›  专栏  ›  技术社区  ›  Klaus

解压包含其他Zip文件的文件

  •  0
  • Klaus  · 技术社区  · 16 年前

    http://www.java2s.com/Code/Java/File-Input-Output/LoadresourcefromJarfile.htm .

    我唯一的困难是,当一个条目本身是一个Jar文件时,如果不先将其写入一个temp文件,我就无法解压缩它。

    下面是我要做的:

     public void load(String jarFileName) throws Exception{
      ZipFile zf = new ZipFile(jarFileName);
      load(zf.entries(),new FileInputStream(jarFileName),zf.size());
     }
     public void load(Enumeration<? extends ZipEntry> enumeration, InputStream             inputStream, int total) throws Exception {
      if(enumeration!=null){
       while (enumeration.hasMoreElements()) {
        ZipEntry ze = (ZipEntry) enumeration.nextElement();
        htSizes.put(ze.getName(), new Integer((int) ze.getSize()));
       }
      }
    
      BufferedInputStream bis = new BufferedInputStream(inputStream);
      ZipInputStream zis = new ZipInputStream(bis);
      ZipEntry ze = null;
      int retrieved=0;
      while ((ze = zis.getNextEntry()) != null) {
       if (ze.isDirectory()) {
        continue;
       }
       int size = (int) ze.getSize();
       if (size == -1 && htSizes.get(ze.getName())!=null) {
        size = ((Integer) htSizes.get(ze.getName())).intValue();
       }
       if(size==-1)
        size=total-retrieved;
       retrieved+=size;
       byte[] b = new byte[(int) size];
       int rb = 0;
       int chunk = 0;
       while (((int) size - rb) > 0) {
        chunk = zis.read(b, rb, (int) size - rb);
        if (chunk == -1) {
         break;
        }
        rb += chunk;
       }
       if(ze.getName().endsWith(".jar")){
        File f=File.createTempFile("temp", System.nanoTime()+"");
        f.deleteOnExit();
        FileOutputStream fos= new FileOutputStream(f);
        fos.write(b);
        fos.close();
        load(f.getAbsolutePath());
       }
    
       else htJarContents.put(ze.getName(), b);
      }
     }
    

    然而,我真正想做的是:

     public void load(String jarFileName) throws Exception{
      ZipFile zf = new ZipFile(jarFileName);
      load(zf.entries(),new FileInputStream(jarFileName),zf.size());
     }
     public void load(Enumeration<? extends ZipEntry> enumeration, InputStream inputStream, int total) throws Exception {
      if(enumeration!=null){
       while (enumeration.hasMoreElements()) {
        ZipEntry ze = (ZipEntry) enumeration.nextElement();
        htSizes.put(ze.getName(), new Integer((int) ze.getSize()));
       }
      }
    
      BufferedInputStream bis = new BufferedInputStream(inputStream);
      ZipInputStream zis = new ZipInputStream(bis);
      ZipEntry ze = null;
      int retrieved=0;
      while ((ze = zis.getNextEntry()) != null) {
       if (ze.isDirectory()) {
        continue;
       }
       int size = (int) ze.getSize();
       if (size == -1 && htSizes.get(ze.getName())!=null) {
        size = ((Integer) htSizes.get(ze.getName())).intValue();
       }
       if(size==-1)
        size=total-retrieved;
       retrieved+=size;
       byte[] b = new byte[(int) size];
       int rb = 0;
       int chunk = 0;
       while (((int) size - rb) > 0) {
        chunk = zis.read(b, rb, (int) size - rb);
        if (chunk == -1) {
         break;
        }
        rb += chunk;
       }
       if(ze.getName().endsWith(".jar")){
        load(null,new ByteArrayOutputstream(b));
       }   
       else htJarContents.put(ze.getName(), b);
      }
     }
    

    有没有办法避免这种情况?

    非常感谢, 克劳斯。

    1 回复  |  直到 16 年前
        1
  •  0
  •   Community Mohan Dere    6 年前

    我不知道你的尺码到底是怎么回事,我想你把它们弄糊涂了。getNextEntry()将流定位在条目的开头。从 http://java.sun.com/javase/6/docs/api/java/util/zip/ZipInputStream.html#getNextEntry()

    public ZipEntry getNextEntry()抛出 IOException异常

    读取下一个ZIP文件 入口和位置流 输入数据的开头。

    public void process(String filename) throws IOException {
        process(filename, new FileInputStream(new File(filename)));
    }
    
    private void process(String filename, InputStream inputStream) throws IOException {
        ZipInputStream zis = new ZipInputStream(inputStream);
        ZipEntry ze = null;
    
        while ((ze = zis.getNextEntry()) != null) {
            if (ze.isDirectory()) {
                continue;
            }
    
            System.out.println(ze.getName() + " " + ze.getSize());
    
            if (ze.getName().endsWith(".jar")) {
                long size = ze.getSize();
    
                byte[] b = new byte[(int) size];
    
                int rb = 0;
                int chunk = 0;
                while (((int) size - rb) > 0) {
                    chunk = zis.read(b, rb, (int) size - rb);
                    if (chunk == -1) {
                        break;
                    }
                    rb += chunk;
                }
                
                process(ze.getName(), new ByteArrayInputStream(b));
            }
        }
    }