Java解压zip

来源:互联网 发布:外国人在淘宝网可以吗 编辑:程序博客网 时间:2024/05/21 10:13

因为项目要支持上传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;}}