Java解压zip

因为项目要支持上传zip包,默认把包中的index.html当成首页来展示,于是星期五做了个Java解压zip文件的模块,没啥难度,要注意的是对于文件夹的特殊处理,避免变成okb的文件;另外由于通常我们的打包习惯是把一个文件夹压缩,这样解压后仍有一层文件夹,进入文件夹之后才是压缩包中的文件,这里也做了处理,下面把代码记录下,以便查阅。

package com.syni.im800.kb.common.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 对上传的ZIP文件进行解压
 * @author linshutao
 * */
public class UnpackZipUtil {
	
	Log log = LogFactory.getLog(getClass());
	private static UnpackZipUtil unpackZipUtil;
	
	/**
	 * 获取UnpackZipUtil实例
	 * */
	public static synchronized UnpackZipUtil getUtilInstance(){
		if(unpackZipUtil == null){
			unpackZipUtil = new UnpackZipUtil();
		}
		return unpackZipUtil;		
	}
	/**
	 * 解压文件,zip文件中含有index.html/index.htm,直接返回该名字,该方法用于解压
	 * @param fromFileInputStream: 文件输入流
	 * @param toFileFolder 解压后存放的文件夹
	 * */
	public String file2Html(InputStream fromFileInputStream, File toFileFolder){
		/**
		 * 由fromFileInputStream构建输入文件
		 * */
		Date date = new Date();
		SimpleDateFormat sdf =new SimpleDateFormat("yyyyMMddHHmmss");
		String timesuffix = sdf.format(date);
		String zipFileName = "zipfile"+timesuffix+".zip";
		File zipInputFile = new File(toFileFolder.toString()+File.separatorChar+zipFileName);
		try {
			OutputStream os = new FileOutputStream(zipInputFile);
			int bytesRead = 0;
			 byte[] buffer = new byte[1024 * 8];
			while ((bytesRead = fromFileInputStream.read(buffer)) != -1) {
					os.write(buffer, 0, bytesRead);
			}
			
			os.close();
			fromFileInputStream.close();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
		boolean hasIndexFile = false;
		String returnStr = "";
		try {		
			ZipFile zipfile = new ZipFile(zipInputFile);
			ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipInputFile));
			ZipEntry zipEntry = null;
			log.info("开始解压...");
			int i = 0;
			//存储第一次解压的文件,考虑处理解压后仍有一层文件夹的情况
			ZipEntry firstZipEntry = null;
			while ((zipEntry = zipInputStream.getNextEntry()) != null) {
				i++;
				String currFileName = zipEntry.getName();
				if(i==1){
					firstZipEntry = new ZipEntry(zipEntry);
				}
				if(currFileName.equalsIgnoreCase("index.html") || currFileName.equalsIgnoreCase("index.htm")){
					returnStr = currFileName;
					hasIndexFile = true;
				}
				log.info(i+":"+currFileName);				
				if(zipEntry.isDirectory()){}
				File temp = new File(toFileFolder, currFileName);
				if (!temp.getParentFile().exists()){
					temp.getParentFile().mkdirs();
				}
				//不对文件夹进行操作,否则文件夹会变成0kb的文件
				if(zipEntry.isDirectory()){
					continue;
				}
				
				OutputStream os = new FileOutputStream(temp);
				
				// 通过ZipFile的getInputStream方法拿到具体的ZipEntry的输入流
				InputStream is = zipfile.getInputStream(zipEntry);
				int len = 0;
				while ((len = is.read()) != -1)
					os.write(len);
					os.close();
					is.close();
			}
			//没检测到index.html/index.htm,且第一个解压的文件是文件夹,可判断为解压后仍有一层文件夹
			if(!hasIndexFile && firstZipEntry.isDirectory()){
				File folder = new File(toFileFolder.getPath()+File.separatorChar+firstZipEntry.getName());
				File[] files = folder.listFiles();
				for(int j=0;j<files.length;++j){
					String filename = files[j].getName();
					if(filename.equalsIgnoreCase("index.html") || filename.equalsIgnoreCase("index.htm")){
						hasIndexFile = true;
						//文件夹解压后文件夹名称已带有文件分隔符
						returnStr = firstZipEntry.getName()+filename;
					}
				}
			}
			zipfile.close();
			zipInputStream.close();
			zipInputFile.delete();//删除上传的zip文件
			if(!hasIndexFile){
				log.info("错误:该压缩文件中没有index.html!请重新上传!");
				return ContentFromFileUtil.FAILED_BY_NO_INDEX_FOR_ZIP;
			}
		} catch (ZipException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return returnStr;
	}
	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值