`
hellsing42
  • 浏览: 258800 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

用J2se的java.util.jar进行jar文件的解压

阅读更多
由于需要做一个在线更新模块,需要在程序里对jar文件解压,测试程序如下
开始的测试程序如下:
package test;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.*;

public class TestJarFile extends Thread {

    
    
    /**
     * @param args
     */
    public TestJarFile(){
       run();
    }
    public void UnJarFile(){
        JarFile xJarFile = null;
        JarEntry xJarEntry;
        Enumeration<JarEntry> enumer;
        BufferedInputStream is = null;
        FileOutputStream fos = null;
        byte data[] = new byte[1024];
        try {
            xJarFile=new JarFile("d:/TestJar.jar");
            if(xJarFile.size()==0) return;
            
            enumer=xJarFile.entries();
            
          [color=red]  
while(enumer.hasMoreElements()){
                xJarEntry= enumer.nextElement();
                if(xJarEntry.isDirectory()){
                    //event
                    continue;
                }
                is=new BufferedInputStream(xJarFile.getInputStream(xJarEntry));
                System.out.println(xJarEntry.getName());
                if(xJarEntry.getName().contains(".MF")) continue;
                fos =new FileOutputStream("D:/TestJar/"+xJarEntry.getName());
                int len=0;
[/color] 
               while((len=is.read(data))!=-1){
                    
                    fos.write(data,0,len);
                    
                }
            }
   
     
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally{
            try{
 [color=greens]         
                fos.flush();
                fos.close();
                is.close();
[/color]
            }
            catch(Exception e){
                
            }
            }
        
    }
      public static void main(String[] args) {
        TestJarFile t=new TestJarFile();
           

    }
    public void run(){
        File xDir=new File("D:/TestJar/");
        long count=9999999l;
        while(true){
            try {
                sleep(1500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            File xFiles[]=xDir.listFiles();
            System.out.println(xFiles.length);
            if(xFiles.length==0){
                
                UnJarFile();
                }
            }
        
            
            
        }
        
    }





    发现确实可以解压,但被解压的jar文件一直被线程占用,不能删除,后来经javaworld版大指点发现问题:
红色部分,每次循环都生成一个input/output stream,但我在finally里(绿色)只处理了最后一个stream的close,导致之前的stream全部没有清除。
解决办法是加上xJarFile.close(),就可以了。
    但是,新问题又来了,虽然被解压的jar包不被线程占用了,但是解出来的文件夹里的文件却被线程占用(解出来的文件),当用完后不能删除。最后怀疑是没有做垃圾回收导致的问题所以在finally里又加上System.gc()这个方法。但这个方法只是标明可以进行垃圾回收,到底回收不回收却用jvm决定,所以并不知道是否安全。
    最后发现使用JarFile.close()并不能关闭输出流 doc上写的是“将关闭以前调用 getInputStream 方法返回的所有输入流。”,输出流还是需要手动清除,System.gc()其实就是代替你清除这些没有回收的内存,为了安全起见改成手动.

package test;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.*;

public class TestJarFile extends Thread {

    
    
    /**
     * @param args
     */
    public TestJarFile(){
       run();
    }
    public void UnJarFile(){
        JarFile xJarFile = null;
        JarEntry xJarEntry;
        Enumeration<JarEntry> enumer;
        BufferedInputStream is = null;
        FileOutputStream fos = null;
        byte data[] = new byte[1024];
        try {
            xJarFile=new JarFile("d:/TestJar.jar");
            if(xJarFile.size()==0) return;
            
            enumer=xJarFile.entries();
            
            while(enumer.hasMoreElements()){
                xJarEntry= enumer.nextElement();
                if(xJarEntry.isDirectory()) continue;
                is=new BufferedInputStream(xJarFile.getInputStream(xJarEntry));
                System.out.println(xJarEntry.getName());
                if(xJarEntry.getName().contains(".MF")) continue;
                fos =new FileOutputStream("D:/TestJar/"+xJarEntry.getName());
                int len=0;
                while((len=is.read(data))!=-1){
                    
                    fos.write(data,0,len);
                    
                }
                fos.flush();
                fos.close();
                fos=null;
                
            }
            
   
     
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally{
            try{
                fos.flush();
                fos.close();
                xJarFile.close();
                is.close();
//                System.gc();
                
            }
            catch(Exception e){
                
            }
            }
        
    }
    public static void main(String[] args) {
        TestJarFile t=new TestJarFile();
           

    }
    public void run(){
        File xDir=new File("D:/TestJar/");
        while(true){
            try {
                sleep(1500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            File xFiles[]=xDir.listFiles();
            System.out.println(xFiles.length);
            if(xFiles.length==0){
                UnJarFile();
                }
            }
        
            
            
        }
        
    }

在第一个while循环里当用完output stream后就立刻清空。最后问题的症结还是在于outputstream的对象没有释放导致的问题发生


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics