• ZIP解压缩文件的工具类【支持多级文件夹|全】


                                  

                                 ZIP解压缩文件的工具类【支持多级文件夹|全】




    作者:Vashon



    网上有非常多的加压缩演示样例代码。可是都仅仅是支持一级文件夹的操作。假设存在多级文件夹的话就不行了。

    本解压缩工具类经过多次检查及重构,终于分享给大家。


    package com.ywx.ziputils;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.Enumeration;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipFile;
    import java.util.zip.ZipOutputStream;
    
    /**
     * ZIP解压缩文件的工具类,文件能够是多级文件夹的结构进行解压,压缩操作.
     * @author yangwenxue(Vashon)
     *
     */
    public class ZipUtil {
    	/**
    	 * 压缩文件操作
    	 * @param filePath 要压缩的文件路径
    	 * @param descDir 压缩文件的保存路径
    	 * @throws IOException 
    	 */
    	public static void zipFiles(String filePath,String descDir) throws IOException{
    		ZipOutputStream zos=null;
    		try {
    			//创建一个zip输出流
    			zos=new ZipOutputStream(new FileOutputStream(descDir));
    			//启动压缩
    			startZip(zos,"",filePath);
    			System.out.println("=============压缩完成=============");
    		} catch (FileNotFoundException e) {
    			//压缩失败。则删除创建的文件
    			File zipFile=new File(descDir);
    			if(zipFile.exists()){
    				zipFile.delete();
    			}
    			e.printStackTrace();
    		}finally{
    			if(zos!=null){
    				try {
    					zos.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    	/**
    	 * 对文件夹中全部文件递归遍历进行压缩
    	 * @param zos 压缩输出流
    	 * @param oppositePath 在zip文件里的相对路径
    	 * @param filePath 要压缩的文件路径
    	 * @throws IOException 
    	 */
    	private static void startZip(ZipOutputStream zos, String oppositePath,
    			String filePath) throws IOException {
    		File file=new File(filePath);
    		if(file.isDirectory()){//假设是压缩文件夹
    			File[] files=file.listFiles();//列出全部文件夹
    			for(int i=0;i<files.length;i++){
    				File aFile=files[i];
    				if(aFile.isDirectory()){//假设是文件夹,改动相对地址
    					String newoppositePath=oppositePath+aFile.getName()+"/";
    					//压缩文件夹。这是关键,创建一个文件夹的条目时。须要在文件夹名后面加多一个"/"
    					ZipEntry entry=new ZipEntry(newoppositePath);
    					zos.putNextEntry(entry);
    					zos.closeEntry();
    					startZip(zos, newoppositePath, aFile.getPath());
    				}else{//假设不是文件夹,则进行压缩
    					zipFile(zos,oppositePath,aFile);
    				}
    			}
    		}else{//假设是压缩文件,直接调用压缩方法进行压缩
    			zipFile(zos, oppositePath, file);
    		}
    	}
    	/**
    	 * 压缩单个文件到文件夹中
    	 * @param zos zip输出流
    	 * @param oppositePath 在zip文件里的相对路径
    	 * @param file 要压缩的文件
    	 */
    	private static void zipFile(ZipOutputStream zos, String oppositePath, File file) {
    		//创建一个zip条目,每一个zip条目都必须是相对于跟路径
    		InputStream is=null;
    		
    		try {
    			ZipEntry entry=new ZipEntry(oppositePath+file.getName());
    			//将条目保存到zip压缩文件其中
    			zos.putNextEntry(entry);
    			//从文件输入流其中读取数据,并将数据写到输出流其中
    			is=new FileInputStream(file);
    			//====这样的压缩速度非常快
    			int length=0;
    			int bufferSize=1024;
    			byte[] buffer=new byte[bufferSize];
    			
    			while((length=is.read(buffer, 0, bufferSize))>=0){
    				zos.write(buffer, 0, length);
    			}
    			
    //===============下面压缩速度非常慢=================			
    //			int temp=0;
    //
    //			while((temp=is.read())!=-1){
    //				zos.write(temp);
    //			}
    //==========================================	
    			zos.closeEntry();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}finally{
    			if(is!=null){
    				try {
    					is.close();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    	/**
    	 * 解压文件操作
    	 * @param zipFilePath zip文件路径
    	 * @param descDir 解压出来的文件保存的文件夹
    	 */
    	public static void unZiFiles(String zipFilePath,String descDir){
    		File zipFile=new File(zipFilePath);
    		File pathFile=new File(descDir);
    		
    		if(!pathFile.exists()){
    			pathFile.mkdirs();
    		}
    		ZipFile zip=null;
    		InputStream in=null;
    		OutputStream out=null;
    		
    		try {
    			zip=new ZipFile(zipFile);
    			Enumeration<?> entries=zip.entries();
    			while(entries.hasMoreElements()){
    				ZipEntry entry=(ZipEntry) entries.nextElement();
    				String zipEntryName=entry.getName();
    				in=zip.getInputStream(entry);
    				
    				String outPath=(descDir+"/"+zipEntryName).replace("\*", "/");
    				//推断路径是否存在,不存在则创建文件路径
    				File file=new File(outPath.substring(0, outPath.lastIndexOf('/')));
    				if(!file.exists()){
    					file.mkdirs();
    				}
    				//推断文件全路径是否为文件夹,假设是上面已经创建,不须要解压
    				if(new File(outPath).isDirectory()){
    					continue;
    				}
    				out=new FileOutputStream(outPath);
    				
    				byte[] buf=new byte[4*1024];
    				int len;
    				while((len=in.read(buf))>=0){
    					out.write(buf, 0, len);
    				}
    				in.close();
    				
    				System.out.println("==================解压完成==================");
    			}
    		} catch (Exception e) {
    			System.out.println("==================解压失败==================");
    			e.printStackTrace();
    		}finally{
    			try {
    				if(zip!=null){
    					zip.close();
    				}
    				if(in!=null){
    					in.close();
    				}
    				if(out!=null){
    					out.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    	@SuppressWarnings("static-access")
    	public static void main(String args[]) throws IOException{
    //		long startTimes=System.currentTimeMillis();
    //		new ZipUtil().zipFiles("f:"+File.separator+"Vashon2Xiaoai", "f:"+File.separator+"Vashon2Xiaoai_vvv.zip");
    //		long times=System.currentTimeMillis()-startTimes;
    //		System.out.println("耗时:"+times/1000+"秒");
    		new ZipUtil().unZiFiles("f:"+File.separator+"Vashon2Xiaoai_vvv.zip", "f:"+File.separator+"vvvvss");
    	}
    }
    



    实践出真知,希望广大读者动手操作。如问题能够反馈。共同探讨。。。


  • 相关阅读:
    VS Code中格式化插件Prettier-Code Formatter设置
    module5-online-jQuery关于动态轮播图的制作
    module5-jQuery 快速网页交互开发
    module5-05-jQuery 事件操作和插件
    module5-04-jQuery 节点操作和元素尺寸
    module5-03-jQuery 排序、入口函数与动画
    选配CPU的时候,最好带上孩子,学会选择才能把握机遇
    选配显示器时带上孩子,体验选配的乐趣,培养财商从细节开始
    家用电脑升级选配硬盘时带上孩子,体验选配,培养财商从细节开始
    科普文,选配内存,常识分享
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7263364.html
Copyright © 2020-2023  润新知