`
hellsing42
  • 浏览: 261695 次
  • 性别: 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的对象没有释放导致的问题发生


分享到:
评论

相关推荐

    jp.sourceforge.qrcode_QRCode.jar二维码编码解码JAR包.zip

    本文将深入探讨名为“jp.sourceforge.qrcode_QRCode.jar”的Java库,它是进行二维码生成和解析的关键工具。 一、QRCode.jar库简介 “jp.sourceforge.qrcode_QRCode.jar”是一个专门用于处理QR码的Java类库,它包含...

    二维码jar包 Qrcode_swetake.jar 与qrcode.jar

    例如,使用`Qrcode_swetake.jar`时,可能需要导入`com.swetake.util.Qrcode`类,而`qrcode.jar`可能需要导入`com.google.zxing.client.j2se.MatrixToImageWriter`等相关类。 在生成二维码的过程中,开发者需要提供...

    java写二维码和解析二维码要用的jar包

    本主题中提到的"java写二维码和解析二维码要用的jar包"指的是使用ZXing(Zebra Crossing)库,这是一个开源的Java项目,提供了多种格式的一维和二维条码读取与生成能力。ZXing的jar包是Java程序员处理二维码功能的...

    二维码jar,QRCode.jar

    在Java中,通常每个类都会有一个.java文件,编译后生成对应的.class文件,这些文件会被打包进JAR(Java Archive)文件中,便于在不同平台上运行。 总的来说,QRCode.jar是一个方便的Java工具,用于生成二维码,适用...

    QRCode及其maven引入方法

    2. **引入依赖**:在Java项目中,如果使用Maven作为构建工具,可以通过在`pom.xml`文件中添加ZXing的依赖来引入库。在`&lt;dependencies&gt;`标签内添加以下代码: ```xml &lt;groupId&gt;com.google.zxing&lt;/groupId&gt; ...

    java生成二维码(源代码和jar)

    本文将详细解析如何使用Java生成二维码,包括带Logo和不带Logo两种方案,并结合提供的源代码和jar文件进行深入探讨。 首先,我们需要了解二维码的基本原理。二维码(Quick Response Code)是一种二维条形码,可以...

    java二维码生成依赖jar包core-3.3.3.jar

    在Java项目中使用ZXing生成二维码,首先需要将`core-3.3.3.jar`添加到项目的类路径中。然后,可以通过`com.google.zxing.client.j2se.MatrixToImageWriter`类将二维码数据转化为图像。以下是一个简单的示例: ```...

    Java使用Zxing包制作二维码.doc

    Java 使用 Zxing 包制作二维码 Java 使用 Zxing 包制作二维码是指使用 Java 语言和 Zxing 库来生成和解析二维码的过程。Zxing 库是 Google 提供的关于条码(一维码、二维码)的解析工具,提供了二维码的生成与解析...

    如何才算掌握Java(J2SE篇

    ### 如何才算真正掌握Java(J2SE篇) 在当今的软件开发领域中,Java作为一门重要的编程语言,被广泛应用于各种应用场景之中。对于初学者来说,如何判定自己是否已经掌握了Java,特别是在J2SE(Java 2 Standard ...

    学好j2se的标准

    第六,学会使用Ant进行项目管理,包括编译、生成文档、创建JAR文件、版本控制和自动化测试,这对于大型项目的组织和维护至关重要。 第七,具备一定的故障排查能力,能够根据堆栈跟踪快速定位问题,并能有效地解决...

    zpxing.jar

    它的Java版本名为core.jar和javase.jar,这两个库文件可以用来在Java环境中处理二维码。在这里,我们关注的是"zxing-2.2.jar",这是ZXing项目的2.2版本的Java库,包含了所有必要的类和方法用于生成二维码。 生成带...

    java生成一维码和二维码程序以及jar包

    本文将深入探讨如何使用Java来创建一维码(如条形码)和二维码,并介绍相关jar包的使用方法。 首先,我们要知道一维码通常包含线性排列的数据,如UPC或EAN,而二维码则是一种二维图形,能够存储更多的信息,如网址...

    Java 1.6 API 中文 New

    java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...

    ASBarcode(java).rar_条码生成 java

    这个"ASBarcode(java).rar"压缩包提供的示例可能包含了上述库中的某一种方法,通过解压并查看源代码,你可以更深入地理解如何在实际项目中应用这些技术。记得根据项目的具体需求选择合适的库和条码类型,以确保最佳...

    JAVA生成Zxing二维码

    如果不使用Maven,可以从Zxing官网下载对应的jar包并添加到项目的类路径中。 2. **生成二维码** 要生成二维码,你需要使用`com.google.zxing.client.j2se.MatrixToImageWriter`和`...

    java实现二维条码,附件:jar包

    下面将详细讲解如何使用Java实现二维条码的生成,并结合"qrcode.jar"这个库进行具体阐述。 首先,"qrcode.jar"是一个用于生成和解码QR码的Java库,可能基于开源项目如ZXing(Zebra Crossing)或者其他的实现。这个...

    java使用Zxing包生成和识别二维码

    在Java项目中使用Zxing进行二维码生成之前,首先需要将Zxing的核心库(core.jar)添加到项目的类路径(classpath)中。如果使用Maven或Gradle等构建工具,则可以通过添加相应的依赖来引入Zxing库。例如,在Maven项目中...

    Java做的记事本程序

    程序可能还使用了java.util.Scanner和java.util.Formatter类进行文本输入和格式化。Scanner用于读取用户的输入,Formatter则可以用来控制文本输出的格式,比如字体、大小和颜色。 此外,事件处理是Java GUI编程的...

    J2SE6.0_Api_CN.zip_J2SE6.0_Api_CN_J2se6.0_apidoc_j2se 6.0_APIDOC

    10. **Java Development Kit (JDK) Tools**:包括编译器`javac`、打包工具`jar`等也进行了升级,提升了开发者的工作效率。 J2SE 6.0的API中文文档详细列出了所有这些特性的使用方法和示例代码,帮助开发者快速掌握...

    如何才算掌握Java(J2SE篇)

    ### 如何才算真正掌握Java(J2SE篇) 在IT领域,尤其是软件开发行业中,Java是一种极为重要的编程语言。很多开发者声称自己“掌握了Java”,但真正的掌握并不仅仅停留在理论层面,而是能够在实践中灵活运用。本文将...

Global site tag (gtag.js) - Google Analytics