zoukankan      html  css  js  c++  java
  • 读写ZIP&JAR文件

      

    1. ZipEntry 是包括目录的,也就是目录也被当做是一个单独的Entry,在列出它下面的文件之前先列出这个directory entry.

      这个在解压ZIP文件的的时候特别有用,我们要先创建这个目录,然后在解压目录下面的文件,否则解压的时候会说目录不存在.

    ZipInputStream zis = new ZipInputStream(new FileInputStream("F:\workspace\HibernateSrc\lib\hibernate3.jar"));
    ZipEntry entry = zis.getNextEntry();

    2.JarEntry是不包括目录的,只包括class文件对应的entry, 要想访问目录,请使用ZipEntry读取Jar文件.

    JarInputStream jis = new JarInputStream(new FileInputStream(mainJar));
    JarEntry entry = jis.getNextJarEntry();

    3. 往jar文件里写数据的时候,要首先调用jos.putNextEntry(entry);放入一个entry记录,然后调用jos.write(temp, 0, count);往对应的记录写数据.

    4. 读entry内容的时候,先要穿件一个JarFile or ZipFile, 然后遍历所有的entry记录,可以直接调用zip.entires()来得到entry的所有记录,也可以对jar&zip文件

       创建一个JarInputStream & ZipInputStream 来遍历entry记录, 当选定了entry后,调用JarFile.getInputStream(entry)来拿到对应entry记录的输入流.

     下面的蓝色部分代码是读入的操作,红色部分代码是输出的操作

            JarFile zipIn = new JarFile(mainJar);
            InputStream readin = null;
            JarOutputStream jos = new JarOutputStream(new FileOutputStream("rt.jar"));
            JarInputStream  jis = new JarInputStream(new FileInputStream(mainJar));
            JarEntry entry = jis.getNextJarEntry();
            while(entry!=null) {
                String name = entry.getName();
                //remove the .class suffix.
                name = name.substring(0,name.lastIndexOf("."));
                if(depencyClass.contains(name)) {
                    //put an entry record and write the binary data
                    jos.putNextEntry(entry);
                    readin = zipIn.getInputStream(entry);
                    byte[] temp = new byte[4096];
                    int count = readin.read(temp);
                    while (count != -1) {
                            jos.write(temp, 0, count);
                            count = readin.read(temp);
                    }
                    readin.close();
                }
                entry = jis.getNextJarEntry();
            }
            jis.close();
            jos.close();

    下面是两个例子

    ReduceJRE是用来抽取Jar里面特定的class文件到一个新的rt.jar

    public class ReduceJRE {
    
    	public static void main(String[] args) throws Exception {
    		String mainJar = null;
    		String classDenpdencyFile = null;
    		if(args!=null && args.length==2)
    		{
    			mainJar = args[0];
    			classDenpdencyFile = args[1];
    		}
    		else {
    			mainJar = "F:\Program Files\Java\jre7\lib\rt.jar";
    			classDenpdencyFile = "F:\Program Files\Java\jre7\lib\classdepency.txt";
    		}
    		List<String> depencyClass = new ArrayList<String>();
    		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(classDenpdencyFile)));
    	    String templine = br.readLine();
    	    // load all the dependency class and store them in a array list;
    	    while(templine!=null) {
    	    	int end = templine.lastIndexOf("from");
    	    	int begin = templine.lastIndexOf("[Loaded")+7;
    	    	String className = templine.substring(begin,end).replace(".", "/").trim();
    	    	depencyClass.add(className);
    	    	templine= br.readLine();
    	    }
    	    JarFile zipIn = new JarFile(mainJar);
            InputStream readin = null;
    	    JarOutputStream jos = new JarOutputStream(new FileOutputStream("rt.jar"));
    	    JarInputStream  jis = new JarInputStream(new FileInputStream(mainJar));
    	    JarEntry entry = jis.getNextJarEntry();
    		while(entry!=null) {
    			String name = entry.getName();
    			//remove the .class suffix.
    			name = name.substring(0,name.lastIndexOf("."));
    			if(depencyClass.contains(name)) {
    				//put an entry record and write the binary data
    				jos.putNextEntry(entry);
    				readin = zipIn.getInputStream(entry);
    		        byte[] temp = new byte[4096];
    		        int count = readin.read(temp);
    		        while (count != -1) {
    		                jos.write(temp, 0, count);
    		                count = readin.read(temp);
    		        }
    		        readin.close();
    			}
    			entry = jis.getNextJarEntry();
    		}
    		jis.close();
    		jos.close();
    	}
    }
    
    extractZIPFile 把spPath指定的ZIP文件解压到destinationDir,如果指定了fileIdentifier,那么久解压指定的文件,否则解压全部文件。
       private String extractZIPFile(String spPath, String destinationDir, String fileIdentifier) throws IOException {
            ZipFile zip = new ZipFile(spPath);
            String rootfolderPath = null;
            FileOutputStream fos = null;
            InputStream readin = null;
    
    		/*create the destination folder if it is non-existed.*/
            File destFolder = new File(destinationDir);
            if (!destFolder.exists()) {
                destFolder.mkdirs();
            }
    
            try {
                for (Enumeration<? extends ZipEntry> enums = zip.entries(); enums.hasMoreElements(); ) {
                    ZipEntry entry = (ZipEntry) enums.nextElement();
    
    				/*if specified the identifier and the current entry does not match it. then just skip this entry*/
                    if (fileIdentifier != null) {
                        if (!entry.getName().contains(fileIdentifier)) {
                            continue;
                        } else {
                            String fileName = destinationDir + separator + entry.getName().substring(entry.getName().lastIndexOf("/"));
                            File f = new File(fileName);
                            rootfolderPath = f.getCanonicalPath();
                            readin = zip.getInputStream(entry);
                            fos = new FileOutputStream(f);
                            byte[] temp = new byte[BUFFER_SIZE];
                            int count = readin.read(temp);
                            while (count != -1) {
                                fos.write(temp, 0, count);
                                count = readin.read(temp);
                            }
                            /*need to close the fos/readin as the fos/readin will be refer to another entry next time*/
                            fos.close();
                            readin.close();
                        }
                    } else {
                        String fileName = destinationDir + separator + entry.getName();
                        File f = new File(fileName);
    
                        if (entry.isDirectory()) {
                            f.mkdirs();
                            if (rootfolderPath == null) {
                                rootfolderPath = f.getCanonicalPath();
                            }
                        } else {
                            readin = zip.getInputStream(entry);
                            fos = new FileOutputStream(f);
                            byte[] temp = new byte[BUFFER_SIZE];
                            int count = readin.read(temp);
                            while (count != -1) {
                                fos.write(temp, 0, count);
                                count = readin.read(temp);
                            }
                            /*need to close the fos/readin as the fos/readin will be refer to another entry next time*/
                            fos.close();
                            readin.close();
                        }
                    }
                }
                return rootfolderPath;
            } catch (Exception e) {
                log.error("Bad file format: " + spPath, e);
                return null;
            } finally {
                UpgradeUtils.close(readin, fos);
                zip.close();
            }
        }
    

      

  • 相关阅读:
    Thymeleaf 异常:Exception processing template "index": An error happened during template parsing (template: "class path resource [templates/index.html]")
    Java 异常 Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date'
    MySQL 查询字段时,区分大小写
    Oracle Database XE 11gR2 SQL 命令行的显示调整
    使用 PL/SQL Developer 导入 .sql 文件
    下载、安装 PL/SQL Developer
    安装、验证安装 Oracle Database XE 11gR2
    下载 Oracle Database XE 11gR2
    MyEclipse 设置打开 jsp 文件的默认编辑器
    Oracle Database XE 11gR2 自带的用户,新建用户,修改用户密码
  • 原文地址:https://www.cnblogs.com/princessd8251/p/3923593.html
Copyright © 2011-2022 走看看